Check-in [6ad4565b78]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:update zint to version 2.5.2
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6ad4565b780354828ad9fad6f877e78104d1f2c0
User & Date: chw 2016-11-11 07:09:37.572
Context
2016-11-11
07:11
minor cleanup in [undroidwish] build scripts regarding zint and snack check-in: db7ebb5b8c user: chw tags: trunk
07:09
update zint to version 2.5.2 check-in: 6ad4565b78 user: chw tags: trunk
2016-11-10
23:13
add missing file to SDL2 directory check-in: 8d6f20d9b4 user: chw tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Added assets/zint2.5.2/demo.tcl.








































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package require Tk
package require zint
wm title . "ZINT Demo"
wm minsize . 480 320
if {[info command sdltk] eq "sdltk"} {
    wm attributes . -fullscreen 1
    set padx 30
    set pady 20
} else {
    wm geometry . 480x320
    set padx 5
    set pady 5
}
image create photo ::zintimg
pack [::ttk::combobox .c -values [lsort [zint symbologies]] -state readonly] \
    -side top -fill x -padx $padx -pady $pady
.c set Datamatrix
pack [::ttk::entry .e] -side top -fill x -padx $padx -pady $pady
.e insert end 12345
bind .e <Return> Generate
pack [::ttk::button .b -text Generate -command Generate] -fill x -side top \
    -padx $padx -pady $pady
proc Generate {} {
    ::zintimg blank
    ::zintimg configure -width 1 -height 1
    ::zintimg blank
    ::zintimg configure -width 0 -height 0
    if {[catch {zint encode [.e get] ::zintimg -barcode [.c get]} e]} {
        tk_messageBox -message $e -title "Zint error"
    } else {
	set w [image width ::zintimg]
	set h [image height ::zintimg]
	set lw [winfo width .l]
	set lh [winfo height .l]
	set sx [expr {int(1.0 * $lw / $w)}]
	set sy [expr {int(1.0 * $lh / $h)}]
	if {$sy < $sx} {
	    set sx $sy
	}
	if {$sx <= 0} {
	    set sx [expr {1.1 * $lw / $w}]
	    set sy [expr {1.1 * $lh / $h}]
	    if {$sy < $sx} {
		set sx $sy
	    }
	}
	::zintimg blank
	::zintimg configure -width 1 -height 1
	::zintimg blank
	::zintimg configure -width 0 -height 0
	catch {
	    zint encode [.e get] ::zintimg -barcode [.c get] -scale $sx
	}
    }
}
pack [label .l -image ::zintimg -bg white] -side top -fill both -expand 1 \
    -padx $padx -pady $pady
bind .e <Configure> {
    after cancel Generate
    after idle Generate
}
bind .c <<ComboboxSelected>> {
    after cancel Generate
    after idle Generate
}
bind all <Break> exit
bind all <Control-q> exit
bind all <Alt-q> exit
Added assets/zint2.5.2/pkgIndex.tcl.




>
>
1
2
package ifneeded zint 2.5.2 \
    [list load libzint[info sharedlibextension] Zint]
Changes to jni/zint/Android.mk.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


37
38
39
40
41
42
43
44
45



46
47

48
49
50
51
52

53
54
55
56
57
58

59
60
61
62
63
64
65

LOCAL_ADDITIONAL_DEPENDENCIES += $(tk_path)/tk-config.mk

LOCAL_C_INCLUDES := $(tcl_includes) $(tk_includes) \
	$(LOCAL_PATH)/../libpng $(LOCAL_PATH)/backend

LOCAL_CFLAGS := $(tcl_cflags) $(tk_cflags) \
	-DZINT_VERSION="\"2.5.0\"" \
	-Dmain=zint \
	-O2

LOCAL_SRC_FILES := \
	backend/2of5.c \
	backend/auspost.c \
	backend/aztec.c \


	backend/code128.c \
	backend/code16k.c \
	backend/code1.c \
	backend/code49.c \
	backend/code.c \
	backend/common.c \
	backend/composite.c \
	backend/dllversion.c \
	backend/dmatrix.c \



	backend/gridmtx.c \
	backend/gs1.c \

	backend/imail.c \
	backend/large.c \
	backend/library.c \
	backend/maxicode.c \
	backend/medical.c \

	backend/pdf417.c \
	backend/plessey.c \
	backend/png.c \
	backend/postal.c \
	backend/ps.c \
	backend/qr.c \

	backend/reedsol.c \
	backend/render.c \
	backend/rss.c \
	backend/svg.c \
	backend/telepen.c \
	backend/upcean.c \
	backend_tcl/zint.c \







|







>
>









>
>
>


>





>






>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

LOCAL_ADDITIONAL_DEPENDENCIES += $(tk_path)/tk-config.mk

LOCAL_C_INCLUDES := $(tcl_includes) $(tk_includes) \
	$(LOCAL_PATH)/../libpng $(LOCAL_PATH)/backend

LOCAL_CFLAGS := $(tcl_cflags) $(tk_cflags) \
	-DZINT_VERSION="\"2.5.2\"" \
	-Dmain=zint \
	-O2

LOCAL_SRC_FILES := \
	backend/2of5.c \
	backend/auspost.c \
	backend/aztec.c \
	backend/bmp.c \
	backend/codablock.c \
	backend/code128.c \
	backend/code16k.c \
	backend/code1.c \
	backend/code49.c \
	backend/code.c \
	backend/common.c \
	backend/composite.c \
	backend/dllversion.c \
	backend/dmatrix.c \
	backend/dotcode.c \
	backend/eci.c \
	backend/gif.c \
	backend/gridmtx.c \
	backend/gs1.c \
	backend/hanxin.c \
	backend/imail.c \
	backend/large.c \
	backend/library.c \
	backend/maxicode.c \
	backend/medical.c \
	backend/pcx.c \
	backend/pdf417.c \
	backend/plessey.c \
	backend/png.c \
	backend/postal.c \
	backend/ps.c \
	backend/qr.c \
	backend/raster.c \
	backend/reedsol.c \
	backend/render.c \
	backend/rss.c \
	backend/svg.c \
	backend/telepen.c \
	backend/upcean.c \
	backend_tcl/zint.c \
Changes to jni/zint/README.
13
14
15
16
17
18
19
20

21

22
23
24












25
26
27
28
29
30
31
Extended Code 39, Code 93, PZN, Code 23, LOGMARS, Codabar, Pharmacode, Code
128, EAN-128, NVE-18, Code 16k, PDF417, MicroPDF417, Two-Track Pharmacode,
PostNet, PLANET, Australia Post 4-State Symbols, RM4SCC, USPS OneCode, GS1
DataBar, DataBar-14, DataBar Limited, DataBar Extended, DataBar Stacked,
Composite Symbology, Data Matrix, QR Code, Maxicode, Aztec Code, EAN-13,
Micro QR, Korea Post Barcode, HIBC Code 128, HIBC Code 39, HIBC Data Matrix,
HIBC PDF417, HIBC MicroPDF417, HIBC QR Code, HIBC Aztec Code, Japanese Postal
Code, Code 49, Channel Code, Code One, Grid Matrix, FIM and Flattermarken.




PROJECT STATUS
--------------












Version 2.3.0:
This release features a complete rebuild of QR Code and Micro QR Code
functionality which now:

* Automatically detects and adjusts to Japanese characters
* Supports GS1 encoding
* Does not require the qrencode library.







|
>

>



>
>
>
>
>
>
>
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Extended Code 39, Code 93, PZN, Code 23, LOGMARS, Codabar, Pharmacode, Code
128, EAN-128, NVE-18, Code 16k, PDF417, MicroPDF417, Two-Track Pharmacode,
PostNet, PLANET, Australia Post 4-State Symbols, RM4SCC, USPS OneCode, GS1
DataBar, DataBar-14, DataBar Limited, DataBar Extended, DataBar Stacked,
Composite Symbology, Data Matrix, QR Code, Maxicode, Aztec Code, EAN-13,
Micro QR, Korea Post Barcode, HIBC Code 128, HIBC Code 39, HIBC Data Matrix,
HIBC PDF417, HIBC MicroPDF417, HIBC QR Code, HIBC Aztec Code, Japanese Postal
Code, Code 49, Channel Code, Code One, Grid Matrix, FIM and Flattermarken,
Codablock-F, DotCode, Han Xin Code.

Output can be saved as BMP, EPS, GIF, PCX, PNG or SVG. 

PROJECT STATUS
--------------
Version 2.5.0:
After a long period of inaction, many new features and bugfixes, including:

* Reintroduction of Codablock-F
* Introduction of symbologies DotCode and Han Xin Code
* New output formats: GIF, BMP and PCX
* ECI handling
* Redesigned handling of batch files at the command line
* Integrate DMRE handling in Data Matrix
* New licensing model


Version 2.3.0:
This release features a complete rebuild of QR Code and Micro QR Code
functionality which now:

* Automatically detects and adjusts to Japanese characters
* Supports GS1 encoding
* Does not require the qrencode library.
Changes to jni/zint/backend/2of5.c.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
};

static inline char check_digit(unsigned int count) {
    return itoc((10 - (count % 10)) % 10);
}

/* Code 2 of 5 Standard (Code 2 of 5 Matrix) */
int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { 

    int i, error_number;
    char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/

    error_number = 0;

    if (length > 80) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* start character */
    strcpy(dest, "411111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25MatrixTable, source[i], dest);
    }

    /* Stop character */
	strcat(dest, "41111");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Industrial */
int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { 

    int i, error_number;
    char dest[512]; /* 6 + 40 * 10 + 6 + 1 */

    error_number = 0;

    if (length > 45) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data");
        return error_number;
    }

    /* start character */
    strcpy(dest, "313111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25IndustTable, source[i], dest);
    }

    /* Stop character */
	strcat(dest, "31113");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 IATA */
int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { 
    int i, error_number;
    char dest[512]; /* 4 + 45 * 10 + 3 + 1 */

    error_number = 0;

    if (length > 45) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* start */
    strcpy(dest, "1111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25IndustTable, source[i], dest);
    }

    /* stop */
	strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Data Logic */
int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { 

    int i, error_number;
    char dest[512]; /* 4 + 80 * 6 + 3 + 1 */

    error_number = 0;

    if (length > 80) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* start character */
    strcpy(dest, "1111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25MatrixTable, source[i], dest);
    }

    /* Stop character */
	strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Interleaved */
int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { 

    int i, j, k, error_number;
    char bars[7], spaces[7], mixed[14], dest[1000];
#ifndef _MSC_VER
    unsigned char temp[length + 2];
#else
    unsigned char* temp = (unsigned char *) _alloca((length + 2) * sizeof (unsigned char));
#endif

    error_number = 0;

    if (length > 89) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    ustrcpy(temp, (unsigned char *) "");
    /* Input must be an even number of characters for Interlaced 2 of 5 to work:
       if an odd number of characters has been entered then add a leading zero */
    if (length & 1) {
        ustrcpy(temp, (unsigned char *) "0");
        length++;
    }
    strcat((char*)temp, (char*)source);

    /* start character */
    strcpy(dest, "1111");

    for (i = 0; i < length; i += 2) {
        /* look up the bars and the spaces and put them in two strings */
        strcpy(bars, "");
        lookup(NEON, C25InterTable, temp[i], bars);
        strcpy(spaces, "");
        lookup(NEON, C25InterTable, temp[i + 1], spaces);

        /* then merge (interlace) the strings together */
        k = 0;
        for (j = 0; j <= 4; j++) {
            mixed[k] = bars[j];
            k++;
            mixed[k] = spaces[j];
            k++;
        }
        mixed[k] = '\0';
		strcat(dest, mixed);
    }

    /* Stop character */
	strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, temp);
    return error_number;

}

/* Interleaved 2-of-5 (ITF) */
int itf14(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, error_number, zeroes;
    unsigned int count;
    char localstr[16];

    error_number = 0;

    count = 0;

    if (length > 13) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data");
        return error_number;
    }

    /* Add leading zeros as required */
    zeroes = 13 - length;
    for (i = 0; i < zeroes; i++) {
        localstr[i] = '0';







|




<
<

|




|











|







|




<
<

|




|











|







|



<
<

|




|











|







|




<
<

|




|











|







|









<
<

|




|










|




















|



|













<
<



|





|







55
56
57
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
};

static inline char check_digit(unsigned int count) {
    return itoc((10 - (count % 10)) % 10);
}

/* Code 2 of 5 Standard (Code 2 of 5 Matrix) */
int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number;
    char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/



    if (length > 80) {
        strcpy(symbol->errtxt, "Input too long (C01)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C02)");
        return error_number;
    }

    /* start character */
    strcpy(dest, "411111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25MatrixTable, source[i], dest);
    }

    /* Stop character */
    strcat(dest, "41111");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Industrial */
int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number;
    char dest[512]; /* 6 + 40 * 10 + 6 + 1 */



    if (length > 45) {
        strcpy(symbol->errtxt, "Input too long (C03)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data (C04)");
        return error_number;
    }

    /* start character */
    strcpy(dest, "313111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25IndustTable, source[i], dest);
    }

    /* Stop character */
    strcat(dest, "31113");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 IATA */
int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, error_number;
    char dest[512]; /* 4 + 45 * 10 + 3 + 1 */



    if (length > 45) {
        strcpy(symbol->errtxt, "Input too long (C05)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C06)");
        return error_number;
    }

    /* start */
    strcpy(dest, "1111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25IndustTable, source[i], dest);
    }

    /* stop */
    strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Data Logic */
int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number;
    char dest[512]; /* 4 + 80 * 6 + 3 + 1 */



    if (length > 80) {
        strcpy(symbol->errtxt, "Input too long (C07)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C08)");
        return error_number;
    }

    /* start character */
    strcpy(dest, "1111");

    for (i = 0; i < length; i++) {
        lookup(NEON, C25MatrixTable, source[i], dest);
    }

    /* Stop character */
    strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, source);
    return error_number;
}

/* Code 2 of 5 Interleaved */
int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length) {

    int i, j, k, error_number;
    char bars[7], spaces[7], mixed[14], dest[1000];
#ifndef _MSC_VER
    unsigned char temp[length + 2];
#else
    unsigned char* temp = (unsigned char *) _alloca((length + 2) * sizeof (unsigned char));
#endif



    if (length > 89) {
        strcpy(symbol->errtxt, "Input too long (C09)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C0A)");
        return error_number;
    }

    ustrcpy(temp, (unsigned char *) "");
    /* Input must be an even number of characters for Interlaced 2 of 5 to work:
       if an odd number of characters has been entered then add a leading zero */
    if (length & 1) {
        ustrcpy(temp, (unsigned char *) "0");
        length++;
    }
    strcat((char*) temp, (char*) source);

    /* start character */
    strcpy(dest, "1111");

    for (i = 0; i < length; i += 2) {
        /* look up the bars and the spaces and put them in two strings */
        strcpy(bars, "");
        lookup(NEON, C25InterTable, temp[i], bars);
        strcpy(spaces, "");
        lookup(NEON, C25InterTable, temp[i + 1], spaces);

        /* then merge (interlace) the strings together */
        k = 0;
        for (j = 0; j <= 4; j++) {
            mixed[k] = bars[j];
            k++;
            mixed[k] = spaces[j];
            k++;
        }
        mixed[k] = '\0';
        strcat(dest, mixed);
    }

    /* Stop character */
    strcat(dest, "311");

    expand(symbol, dest);
    ustrcpy(symbol->text, temp);
    return error_number;

}

/* Interleaved 2-of-5 (ITF) */
int itf14(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, error_number, zeroes;
    unsigned int count;
    char localstr[16];



    count = 0;

    if (length > 13) {
        strcpy(symbol->errtxt, "Input too long (C0B)");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data (C0D)");
        return error_number;
    }

    /* Add leading zeros as required */
    zeroes = 13 - length;
    for (i = 0; i < zeroes; i++) {
        localstr[i] = '0';
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
    localstr[14] = '\0';
    error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char*) localstr);
    return error_number;
}

/* Deutshe Post Leitcode */
int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) { 
    int i, error_number;
    unsigned int count;
    char localstr[16];
    int zeroes;

    error_number = 0;
    count = 0;
    if (length > 13) {
        strcpy(symbol->errtxt, "Input wrong length");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    zeroes = 13 - length;
    for (i = 0; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);







|





<


|




|







280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    localstr[14] = '\0';
    error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char*) localstr);
    return error_number;
}

/* Deutshe Post Leitcode */
int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, error_number;
    unsigned int count;
    char localstr[16];
    int zeroes;


    count = 0;
    if (length > 13) {
        strcpy(symbol->errtxt, "Input wrong length (C0E)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C0D)");
        return error_number;
    }

    zeroes = 13 - length;
    for (i = 0; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
    localstr[14] = '\0';
    error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char*) localstr);
    return error_number;
}

/* Deutsche Post Identcode */
int dpident(struct zint_symbol *symbol, unsigned char source[], int length) { 
    int i, error_number, zeroes;
    unsigned int count;
    char localstr[16];

    count = 0;
    if (length > 11) {
        strcpy(symbol->errtxt, "Input wrong length");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    zeroes = 11 - length;
    for (i = 0; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);







|






|




|







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    localstr[14] = '\0';
    error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char*) localstr);
    return error_number;
}

/* Deutsche Post Identcode */
int dpident(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, error_number, zeroes;
    unsigned int count;
    char localstr[16];

    count = 0;
    if (length > 11) {
        strcpy(symbol->errtxt, "Input wrong length (C0E)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C0F)");
        return error_number;
    }

    zeroes = 11 - length;
    for (i = 0; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);
Changes to jni/zint/backend/CMakeLists.txt.
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23

24

25
26
27
28
# (c) 2008 by BogDan Vatra < bogdan@licentia.eu >

project(zint)

find_package(PNG)

set(zint_COMMON_SRCS common.c library.c render.c ps.c large.c reedsol.c gs1.c svg.c png.c)
set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c)
set(zint_POSTAL_SRCS postal.c auspost.c imail.c)
set(zint_TWODIM_SRCS code16k.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c)

set(zint_SRCS ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS} )

if(PNG_FOUND)
    include_directories( ${PNG_INCLUDES} )
else(PNG_FOUND)
    add_definitions (-DNO_PNG)
endif(PNG_FOUND)

add_library(zint SHARED ${zint_SRCS})

set_target_properties(zint PROPERTIES 	SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}"
					VERSION ${ZINT_VERSION})


target_link_libraries(zint ${PNG_LIBRARIES} )

target_link_libraries(zint -lm)

install(TARGETS zint  ${INSTALL_TARGETS_DEFAULT_ARGS} )
install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)






|


|
>
|












>
|
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# (c) 2008 by BogDan Vatra < bogdan@licentia.eu >

project(zint)

find_package(PNG)

set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c eci.c)
set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c)
set(zint_POSTAL_SRCS postal.c auspost.c imail.c)
set(zint_TWODIM_SRCS code16k.c codablock.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c)
set(zint_OUTPUT_SRCS render.c ps.c svg.c bmp.c pcx.c gif.c png.c raster.c)
set(zint_SRCS ${zint_OUTPUT_SRCS} ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS})

if(PNG_FOUND)
    include_directories( ${PNG_INCLUDES} )
else(PNG_FOUND)
    add_definitions (-DNO_PNG)
endif(PNG_FOUND)

add_library(zint SHARED ${zint_SRCS})

set_target_properties(zint PROPERTIES 	SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}"
					VERSION ${ZINT_VERSION})

if(PNG_FOUND)
    target_link_libraries(zint ${PNG_LIBRARIES} )
endif(PNG_FOUND)
target_link_libraries(zint -lm)

install(TARGETS zint  ${INSTALL_TARGETS_DEFAULT_ARGS} )
install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
Changes to jni/zint/backend/auspost.c.
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
    /* The contents of data_pattern conform to the following standard:
       0 = Tracker, Ascender and Descender
       1 = Tracker and Ascender
       2 = Tracker and Descender
       3 = Tracker only */
    int error_number, zeroes;
    int writer;
    unsigned int loopey, reader, h;


    char data_pattern[200];
    char fcc[3] = {0, 0, 0}, dpid[10];
    char localstr[30];

    error_number = 0;
    strcpy(localstr, "");







|
>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    /* The contents of data_pattern conform to the following standard:
       0 = Tracker, Ascender and Descender
       1 = Tracker and Ascender
       2 = Tracker and Descender
       3 = Tracker only */
    int error_number, zeroes;
    int writer;
    unsigned int loopey, reader;
    size_t h;

    char data_pattern[200];
    char fcc[3] = {0, 0, 0}, dpid[10];
    char localstr[30];

    error_number = 0;
    strcpy(localstr, "");
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
                strcpy(fcc, "62");
                break;
            case 23:
                strcpy(fcc, "62");
                error_number = is_sane(NEON, source, length);
                break;
            default:
                strcpy(symbol->errtxt, "Auspost input is wrong length");
                return ZINT_ERROR_TOO_LONG;
        }
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in data");
            return error_number;
        }
    } else {
        if (length > 8) {
            strcpy(symbol->errtxt, "Auspost input is too long");
            return ZINT_ERROR_TOO_LONG;
        }
        switch (symbol->symbology) {
            case BARCODE_AUSREPLY: strcpy(fcc, "45");
                break;
            case BARCODE_AUSROUTE: strcpy(fcc, "87");
                break;







|



|




|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
                strcpy(fcc, "62");
                break;
            case 23:
                strcpy(fcc, "62");
                error_number = is_sane(NEON, source, length);
                break;
            default:
                strcpy(symbol->errtxt, "Auspost input is wrong length (D01)");
                return ZINT_ERROR_TOO_LONG;
        }
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in data (D02)");
            return error_number;
        }
    } else {
        if (length > 8) {
            strcpy(symbol->errtxt, "Auspost input is too long (D03)");
            return ZINT_ERROR_TOO_LONG;
        }
        switch (symbol->symbology) {
            case BARCODE_AUSREPLY: strcpy(fcc, "45");
                break;
            case BARCODE_AUSROUTE: strcpy(fcc, "87");
                break;
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
        localstr[8] = '\0';
    }

    strcat(localstr, (char*) source);
    h = strlen(localstr);
    error_number = is_sane(GDSET, (unsigned char *) localstr, h);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* Verifiy that the first 8 characters are numbers */
    memcpy(dpid, localstr, 8);
    dpid[8] = '\0';
    error_number = is_sane(NEON, (unsigned char *) dpid, strlen(dpid));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in DPID");
        return error_number;
    }

    /* Start character */
    strcpy(data_pattern, "13");

    /* Encode the FCC */







|








|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
        localstr[8] = '\0';
    }

    strcat(localstr, (char*) source);
    h = strlen(localstr);
    error_number = is_sane(GDSET, (unsigned char *) localstr, h);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D04)");
        return error_number;
    }

    /* Verifiy that the first 8 characters are numbers */
    memcpy(dpid, localstr, 8);
    dpid[8] = '\0';
    error_number = is_sane(NEON, (unsigned char *) dpid, strlen(dpid));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in DPID (D05)");
        return error_number;
    }

    /* Start character */
    strcpy(data_pattern, "13");

    /* Encode the FCC */
Changes to jni/zint/backend/aztec.c.
36
37
38
39
40
41
42


43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
















91




92
93
94
95
96
97
98
#ifdef _MSC_VER
#include <malloc.h> 
#endif
#include "common.h"
#include "aztec.h"
#include "reedsol.h"



/**
 * Shorten the string by one character
 */
void mapshorten(int *charmap, int *typemap, int start, int length) {
    memmove(charmap + start + 1, charmap + start + 2, (length - 1) * sizeof (int));
    memmove(typemap + start + 1, typemap + start + 2, (length - 1) * sizeof (int));
}

/**
 * Insert a character into the middle of a string at position posn
 */

void insert(char binary_string[], int posn, char newbit) {
    size_t i, end;

    end = strlen(binary_string);
    for (i = end; i > posn; i--) {
        binary_string[i] = binary_string[i - 1];
    }
    binary_string[posn] = newbit;
}


/**
 * Encode input data into a binary string
 */
int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1) {
    int i, j, k, p, bytes;
    int curtable, newtable, lasttable, chartype, maplength, blocks, debug;
#ifndef _MSC_VER
    int charmap[src_len * 2], typemap[src_len * 2];
    int blockmap[2][src_len];
#else
    int* charmap = (int*) _alloca(src_len * 2 * sizeof (int));
    int* typemap = (int*) _alloca(src_len * 2 * sizeof (int));
    int* blockmap[2];
    blockmap[0] = (int*) _alloca(src_len * sizeof (int));
    blockmap[1] = (int*) _alloca(src_len * sizeof (int));
#endif
    /* Lookup input string in encoding table */
    maplength = 0;
    debug = 0;

    for (i = 0; i < (int) src_len; i++) {
        if (gs1 && (i == 0)) {
            /* Add FNC1 to beginning of GS1 messages */
            charmap[maplength] = 0;
            typemap[maplength++] = PUNC;
            charmap[maplength] = 400;
            typemap[maplength++] = PUNC;
















        }




        if ((gs1) && (source[i] == '[')) {
            /* FNC1 represented by FLG(0) */
            charmap[maplength] = 0;
            typemap[maplength++] = PUNC;
            charmap[maplength] = 400;
            typemap[maplength++] = PUNC;
        } else {







>
>



|







>
|








>




|
















<
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifdef _MSC_VER
#include <malloc.h> 
#endif
#include "common.h"
#include "aztec.h"
#include "reedsol.h"

static int AztecMap[22801];

/**
 * Shorten the string by one character
 */
static void mapshorten(int *charmap, int *typemap, const int start, const int length) {
    memmove(charmap + start + 1, charmap + start + 2, (length - 1) * sizeof (int));
    memmove(typemap + start + 1, typemap + start + 2, (length - 1) * sizeof (int));
}

/**
 * Insert a character into the middle of a string at position posn
 */
/*
static void insert(char binary_string[], const size_t posn, const char newbit) {
    size_t i, end;

    end = strlen(binary_string);
    for (i = end; i > posn; i--) {
        binary_string[i] = binary_string[i - 1];
    }
    binary_string[posn] = newbit;
}
*/

/**
 * Encode input data into a binary string
 */
static int aztec_text_process(const unsigned char source[], const unsigned int src_len, char binary_string[], const int gs1, const int eci) {
    int i, j, k, p, bytes;
    int curtable, newtable, lasttable, chartype, maplength, blocks, debug;
#ifndef _MSC_VER
    int charmap[src_len * 2], typemap[src_len * 2];
    int blockmap[2][src_len];
#else
    int* charmap = (int*) _alloca(src_len * 2 * sizeof (int));
    int* typemap = (int*) _alloca(src_len * 2 * sizeof (int));
    int* blockmap[2];
    blockmap[0] = (int*) _alloca(src_len * sizeof (int));
    blockmap[1] = (int*) _alloca(src_len * sizeof (int));
#endif
    /* Lookup input string in encoding table */
    maplength = 0;
    debug = 0;


    if (gs1) {
        /* Add FNC1 to beginning of GS1 messages */
        charmap[maplength] = 0;
        typemap[maplength++] = PUNC;
        charmap[maplength] = 400;
        typemap[maplength++] = PUNC;
    } else if (eci != 3) {
        /* Set ECI mode */
        charmap[maplength] = 0;
        typemap[maplength++] = PUNC;
        if (eci < 10) {
            charmap[maplength] = 401; // FLG(1)
            typemap[maplength++] = PUNC;
            charmap[maplength] = 502 + eci;
            typemap[maplength++] = PUNC;
        } else {
            charmap[maplength] = 402; // FLG(2)
            typemap[maplength++] = PUNC;
            charmap[maplength] = 502 + (eci / 10);
            typemap[maplength++] = PUNC;
            charmap[maplength] = 502 + (eci % 10);
            typemap[maplength++] = PUNC;
        }

    }

    for (i = 0; i < (int) src_len; i++) {
        if ((gs1) && (source[i] == '[')) {
            /* FNC1 represented by FLG(0) */
            charmap[maplength] = 0;
            typemap[maplength++] = PUNC;
            charmap[maplength] = 400;
            typemap[maplength++] = PUNC;
        } else {
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
            blockmap[0][blocks - 1] = 4;
        }
        if (blockmap[0][blocks - 1] & 8) {
            blockmap[0][blocks - 1] = 8;
        }

        /* look for adjacent blocks which can use the same table (right to left search) */
        for (i = blocks - 1; i > 0; i--) {
            if (blockmap[0][i] & blockmap[0][i + 1]) {
                blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]);
            }
        }

        /* determine the encoding table for characters which do not fit with adjacent blocks */
        for (i = 1; i < blocks; i++) {







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
            blockmap[0][blocks - 1] = 4;
        }
        if (blockmap[0][blocks - 1] & 8) {
            blockmap[0][blocks - 1] = 8;
        }

        /* look for adjacent blocks which can use the same table (right to left search) */
        for (i = blocks - 1 - 1; i >= 0; i--) {
            if (blockmap[0][i] & blockmap[0][i + 1]) {
                blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]);
            }
        }

        /* determine the encoding table for characters which do not fit with adjacent blocks */
        for (i = 1; i < blocks; i++) {
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
        }

        /* Combine blocks of the same type */
        i = 0;
        do {
            if (blockmap[0][i] == blockmap[0][i + 1]) {
                blockmap[1][i] += blockmap[1][i + 1];
                for (j = i + 1; j < blocks; j++) {
                    blockmap[0][j] = blockmap[0][j + 1];
                    blockmap[1][j] = blockmap[1][j + 1];
                }
                blocks--;
            } else {
                i++;
            }
        } while (i < blocks);
    }

    /* Put the adjusted block data back into typemap */
    j = 0;
    for (i = 0; i < blocks; i++) {
        if ((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) {
            /* Shift character(s) needed */







|







|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
        }

        /* Combine blocks of the same type */
        i = 0;
        do {
            if (blockmap[0][i] == blockmap[0][i + 1]) {
                blockmap[1][i] += blockmap[1][i + 1];
                for (j = i + 1; j < blocks - 1; j++) {
                    blockmap[0][j] = blockmap[0][j + 1];
                    blockmap[1][j] = blockmap[1][j + 1];
                }
                blocks--;
            } else {
                i++;
            }
        } while (i < blocks - 1);
    }

    /* Put the adjusted block data back into typemap */
    j = 0;
    for (i = 0; i < blocks; i++) {
        if ((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) {
            /* Shift character(s) needed */
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
            }
            if (typemap[i] > 64) {
                /* Shift character */
                switch (typemap[i]) {
                    case (64 + UPPER): /* To UPPER */
                        switch (curtable) {
                            case LOWER: /* US */
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("US ");
                                break;
                            case MIXED: /* UL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case PUNC: /* UL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case DIGIT: /* US */
                                strcat(binary_string, pentbit[15]);
                                if (debug) printf("US ");
                                break;
                        }
                        break;
                    case (64 + LOWER): /* To LOWER */
                        switch (curtable) {
                            case UPPER: /* LL */
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case MIXED: /* LL */
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case PUNC: /* UL LL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case DIGIT: /* UL LL */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                        }
                        break;
                    case (64 + MIXED): /* To MIXED */
                        switch (curtable) {
                            case UPPER: /* ML */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case LOWER: /* ML */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case PUNC: /* UL ML */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case DIGIT: /* UL ML */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                        }
                        break;
                    case (64 + PUNC): /* To PUNC */
                        switch (curtable) {
                            case UPPER: /* PS */
                                strcat(binary_string, hexbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case LOWER: /* PS */
                                strcat(binary_string, hexbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case MIXED: /* PS */
                                strcat(binary_string, hexbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case DIGIT: /* PS */
                                strcat(binary_string, pentbit[0]);
                                if (debug) printf("PS ");
                                break;
                        }
                        break;
                    case (64 + DIGIT): /* To DIGIT */
                        switch (curtable) {
                            case UPPER: /* DL */
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case LOWER: /* DL */
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case MIXED: /* UL DL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case PUNC: /* UL DL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                        }
                        break;
                }
            } else {
                /* Latch character */
                switch (typemap[i]) {
                    case UPPER: /* To UPPER */
                        switch (curtable) {
                            case LOWER: /* ML UL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case MIXED: /* UL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case PUNC: /* UL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case DIGIT: /* UL */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                        }
                        break;
                    case LOWER: /* To LOWER */
                        switch (curtable) {
                            case UPPER: /* LL */
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case MIXED: /* LL */
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case PUNC: /* UL LL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case DIGIT: /* UL LL */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                        }
                        break;
                    case MIXED: /* To MIXED */
                        switch (curtable) {
                            case UPPER: /* ML */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case LOWER: /* ML */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case PUNC: /* UL ML */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case DIGIT: /* UL ML */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                        }
                        break;
                    case PUNC: /* To PUNC */
                        switch (curtable) {
                            case UPPER: /* ML PL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case LOWER: /* ML PL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case MIXED: /* PL */
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case DIGIT: /* UL ML PL */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                        }
                        break;
                    case DIGIT: /* To DIGIT */
                        switch (curtable) {
                            case UPPER: /* DL */
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case LOWER: /* DL */
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case MIXED: /* UL DL */
                                strcat(binary_string, hexbit[29]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case PUNC: /* UL DL */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                        }
                        break;
                    case BINARY: /* To BINARY */
                        lasttable = curtable;
                        switch (curtable) {
                            case UPPER: /* BS */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case LOWER: /* BS */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case MIXED: /* BS */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case PUNC: /* UL BS */
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("BS ");
                                lasttable = UPPER;
                                newtable = BINARY;
                                break;
                            case DIGIT: /* UL BS */
                                strcat(binary_string, pentbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, hexbit[31]);
                                if (debug) printf("BS ");
                                lasttable = UPPER;
                                newtable = BINARY;
                                break;
                        }

                        bytes = 0;







|



|




|




|







|




|




|

|




|

|








|




|




|

|




|

|








|



|



|



|







|




|




|

|




|

|












|

|




|




|




|








|




|




|

|




|

|








|




|




|

|




|

|








|

|




|

|




|




|

|

|








|




|




|

|




|

|









|




|




|




|

|





|

|







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
            }
            if (typemap[i] > 64) {
                /* Shift character */
                switch (typemap[i]) {
                    case (64 + UPPER): /* To UPPER */
                        switch (curtable) {
                            case LOWER: /* US */
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("US ");
                                break;
                            case MIXED: /* UL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case PUNC: /* UL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case DIGIT: /* US */
                                strcat(binary_string, quadbit[15]);
                                if (debug) printf("US ");
                                break;
                        }
                        break;
                    case (64 + LOWER): /* To LOWER */
                        switch (curtable) {
                            case UPPER: /* LL */
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case MIXED: /* LL */
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case PUNC: /* UL LL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case DIGIT: /* UL LL */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                        }
                        break;
                    case (64 + MIXED): /* To MIXED */
                        switch (curtable) {
                            case UPPER: /* ML */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case LOWER: /* ML */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case PUNC: /* UL ML */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case DIGIT: /* UL ML */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                        }
                        break;
                    case (64 + PUNC): /* To PUNC */
                        switch (curtable) {
                            case UPPER: /* PS */
                                strcat(binary_string, pentbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case LOWER: /* PS */
                                strcat(binary_string, pentbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case MIXED: /* PS */
                                strcat(binary_string, pentbit[0]);
                                if (debug) printf("PS ");
                                break;
                            case DIGIT: /* PS */
                                strcat(binary_string, quadbit[0]);
                                if (debug) printf("PS ");
                                break;
                        }
                        break;
                    case (64 + DIGIT): /* To DIGIT */
                        switch (curtable) {
                            case UPPER: /* DL */
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case LOWER: /* DL */
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case MIXED: /* UL DL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case PUNC: /* UL DL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                        }
                        break;
                }
            } else {
                /* Latch character */
                switch (typemap[i]) {
                    case UPPER: /* To UPPER */
                        switch (curtable) {
                            case LOWER: /* ML UL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case MIXED: /* UL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case PUNC: /* UL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                            case DIGIT: /* UL */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                newtable = UPPER;
                                break;
                        }
                        break;
                    case LOWER: /* To LOWER */
                        switch (curtable) {
                            case UPPER: /* LL */
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case MIXED: /* LL */
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case PUNC: /* UL LL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                            case DIGIT: /* UL LL */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[28]);
                                if (debug) printf("LL ");
                                newtable = LOWER;
                                break;
                        }
                        break;
                    case MIXED: /* To MIXED */
                        switch (curtable) {
                            case UPPER: /* ML */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case LOWER: /* ML */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case PUNC: /* UL ML */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                            case DIGIT: /* UL ML */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                newtable = MIXED;
                                break;
                        }
                        break;
                    case PUNC: /* To PUNC */
                        switch (curtable) {
                            case UPPER: /* ML PL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case LOWER: /* ML PL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case MIXED: /* PL */
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                            case DIGIT: /* UL ML PL */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("ML ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("PL ");
                                newtable = PUNC;
                                break;
                        }
                        break;
                    case DIGIT: /* To DIGIT */
                        switch (curtable) {
                            case UPPER: /* DL */
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case LOWER: /* DL */
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case MIXED: /* UL DL */
                                strcat(binary_string, pentbit[29]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                            case PUNC: /* UL DL */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[30]);
                                if (debug) printf("DL ");
                                newtable = DIGIT;
                                break;
                        }
                        break;
                    case BINARY: /* To BINARY */
                        lasttable = curtable;
                        switch (curtable) {
                            case UPPER: /* BS */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case LOWER: /* BS */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case MIXED: /* BS */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("BS ");
                                newtable = BINARY;
                                break;
                            case PUNC: /* UL BS */
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("BS ");
                                lasttable = UPPER;
                                newtable = BINARY;
                                break;
                            case DIGIT: /* UL BS */
                                strcat(binary_string, quadbit[14]);
                                if (debug) printf("UL ");
                                strcat(binary_string, pentbit[31]);
                                if (debug) printf("BS ");
                                lasttable = UPPER;
                                newtable = BINARY;
                                break;
                        }

                        bytes = 0;
660
661
662
663
664
665
666
667
668
669



670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
            chartype -= 64;
        }
        switch (chartype) {
            case UPPER:
            case LOWER:
            case MIXED:
            case PUNC:
                if (charmap[i] >= 400) {
                    strcat(binary_string, tribit[charmap[i] - 400]);
                    if (debug) printf("FLG(%d) ", charmap[i] - 400);



                } else {
                    strcat(binary_string, hexbit[charmap[i]]);
                    if (!((chartype == PUNC) && (charmap[i] == 0)))
                        if (debug) printf("%d ", charmap[i]);
                }
                break;
            case DIGIT:
                strcat(binary_string, pentbit[charmap[i]]);
                if (debug) printf("%d ", charmap[i]);
                break;
            case BINARY:
                for (p = 0; p < 8; p++) {
                    if (charmap[i] & (0x80 >> p)) {
                        strcat(binary_string, "1");
                    } else {







|


>
>
>

|





|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
            chartype -= 64;
        }
        switch (chartype) {
            case UPPER:
            case LOWER:
            case MIXED:
            case PUNC:
                if ((charmap[i] >= 400) && (charmap[i] < 500)) {
                    strcat(binary_string, tribit[charmap[i] - 400]);
                    if (debug) printf("FLG(%d) ", charmap[i] - 400);
                } else if (charmap[i] >= 500) {
                    strcat(binary_string, quadbit[charmap[i] - 500]);
                    if (debug) printf("[%d] ", charmap[i] - 500);
                } else {
                    strcat(binary_string, pentbit[charmap[i]]);
                    if (!((chartype == PUNC) && (charmap[i] == 0)))
                        if (debug) printf("%d ", charmap[i]);
                }
                break;
            case DIGIT:
                strcat(binary_string, quadbit[charmap[i]]);
                if (debug) printf("%d ", charmap[i]);
                break;
            case BINARY:
                for (p = 0; p < 8; p++) {
                    if (charmap[i] & (0x80 >> p)) {
                        strcat(binary_string, "1");
                    } else {
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
        return ZINT_ERROR_TOO_LONG;
    }

    return 0;
}

/* Prevent data from obscuring reference grid */
int avoidReferenceGrid(int input) {
    int output;

    output = input;
    if (output > 10) {
        output++;
    }
    if (output > 26) {
        output++;
    }
    if (output > 42) {







|
<

<







723
724
725
726
727
728
729
730

731

732
733
734
735
736
737
738
        return ZINT_ERROR_TOO_LONG;
    }

    return 0;
}

/* Prevent data from obscuring reference grid */
static int avoidReferenceGrid(int output) {



    if (output > 10) {
        output++;
    }
    if (output > 26) {
        output++;
    }
    if (output > 42) {
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
        output++;
    }

    return output;
}

/* Calculate the position of the bits in the grid */
void popilate_map() {
    int layer, start, length, n, i;
    int x, y;

    for (x = 0; x < 151; x++) {
        for (y = 0; y < 151; y++) {
            AztecMap[(x * 151) + y] = 0;
        }







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
        output++;
    }

    return output;
}

/* Calculate the position of the bits in the grid */
static void populate_map() {
    int layer, start, length, n, i;
    int x, y;

    for (x = 0; x < 151; x++) {
        for (y = 0; y < 151; y++) {
            AztecMap[(x * 151) + y] = 0;
        }
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
    char adjusted_string[20000];
    unsigned char desc_data[4], desc_ecc[6];
    int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length;
    int remainder, padbits, count, gs1, adjustment_size;
    int debug = 0, reader = 0;
    int comp_loop = 4;

#ifndef _MSC_VER
    unsigned char local_source[length + 1];
#else
    unsigned char* local_source = (unsigned char*) _alloca(length + 1);
    unsigned int* data_part;
    unsigned int* ecc_part;
#endif

    memset(binary_string, 0, 20000);
    memset(adjusted_string, 0, 20000);

    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
    } else {
        gs1 = 0;
    }
    if (symbol->output_options & READER_INIT) {
        reader = 1;
        comp_loop = 1;
    }
    if ((gs1 == 1) && (reader == 1)) {
        strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time");
        return ZINT_ERROR_INVALID_OPTION;
    }

    switch (symbol->input_mode) {
        case DATA_MODE:
        case GS1_MODE:
            memcpy(local_source, source, length);
            local_source[length] = '\0';
            break;
        case UNICODE_MODE:
            err_code = latin1_process(symbol, source, local_source, &length);
            if (err_code != 0) {
                return err_code;
            }
            break;
    }

    err_code = aztec_text_process(local_source, length, binary_string, gs1);


    if (err_code != 0) {
        strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters");
        return err_code;
    }

    if (!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) {
        strcpy(symbol->errtxt, "Invalid error correction level - using default instead");
        err_code = ZINT_WARN_INVALID_OPTION;
        symbol->option_1 = -1;
    }

    ecc_level = symbol->option_1;

    if ((ecc_level == -1) || (ecc_level == 0)) {
        ecc_level = 2;
    }

    data_length = strlen(binary_string);

    layers = 0; /* Keep compiler happy! */
    data_maxsize = 0; /* Keep compiler happy! */
    adjustment_size = 0;
    if (symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */
        do {
            /* Decide what size symbol to use - the smallest that fits the data */







|
<
<
<
















|
|



<
<
<
<
<
|
<
<
<
<
|
<
<
<
|

<

|




|










|







885
886
887
888
889
890
891
892



893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913





914




915



916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
    char adjusted_string[20000];
    unsigned char desc_data[4], desc_ecc[6];
    int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length;
    int remainder, padbits, count, gs1, adjustment_size;
    int debug = 0, reader = 0;
    int comp_loop = 4;

#ifdef _MSC_VER



    unsigned int* data_part;
    unsigned int* ecc_part;
#endif

    memset(binary_string, 0, 20000);
    memset(adjusted_string, 0, 20000);

    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
    } else {
        gs1 = 0;
    }
    if (symbol->output_options & READER_INIT) {
        reader = 1;
        comp_loop = 1;
    }
    if (gs1 && reader) {
        strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time (E01)");
        return ZINT_ERROR_INVALID_OPTION;
    }






    populate_map();








    err_code = aztec_text_process(source, length, binary_string, gs1, symbol->eci);


    if (err_code != 0) {
        strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters (E02)");
        return err_code;
    }

    if (!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) {
        strcpy(symbol->errtxt, "Invalid error correction level - using default instead (E03)");
        err_code = ZINT_WARN_INVALID_OPTION;
        symbol->option_1 = -1;
    }

    ecc_level = symbol->option_1;

    if ((ecc_level == -1) || (ecc_level == 0)) {
        ecc_level = 2;
    }

    data_length = (int) strlen(binary_string);

    layers = 0; /* Keep compiler happy! */
    data_maxsize = 0; /* Keep compiler happy! */
    adjustment_size = 0;
    if (symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */
        do {
            /* Decide what size symbol to use - the smallest that fits the data */
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
                            data_maxsize = AztecCompact50DataSizes[i - 1];
                        }
                    }
                    break;
            }

            if (layers == 0) { /* Couldn't find a symbol which fits the data */
                strcpy(symbol->errtxt, "Input too long (too many bits for selected ECC)");
                return ZINT_ERROR_TOO_LONG;
            }

            /* Determine codeword bitlength - Table 3 */
            codeword_size = 6; /* if (layers <= 2) */
            if ((layers >= 3) && (layers <= 8)) {
                codeword_size = 8;







|







1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
                            data_maxsize = AztecCompact50DataSizes[i - 1];
                        }
                    }
                    break;
            }

            if (layers == 0) { /* Couldn't find a symbol which fits the data */
                strcpy(symbol->errtxt, "Input too long (too many bits for selected ECC) (E04)");
                return ZINT_ERROR_TOO_LONG;
            }

            /* Determine codeword bitlength - Table 3 */
            codeword_size = 6; /* if (layers <= 2) */
            if ((layers >= 3) && (layers <= 8)) {
                codeword_size = 8;
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
                    }
                }
                adjusted_string[j] = binary_string[i];
                j++;
                i++;
            } while (i <= (data_length + 1));
            adjusted_string[j] = '\0';
            adjusted_length = strlen(adjusted_string);
            adjustment_size = adjusted_length - data_length;

            /* Add padding */
            remainder = adjusted_length % codeword_size;

            padbits = codeword_size - remainder;
            if (padbits == codeword_size) {
                padbits = 0;
            }

            for (i = 0; i < padbits; i++) {
                strcat(adjusted_string, "1");
            }
            adjusted_length = strlen(adjusted_string);

            count = 0;
            for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
                if (adjusted_string[i] == '1') {
                    count++;
                }
            }







|













|







1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
                    }
                }
                adjusted_string[j] = binary_string[i];
                j++;
                i++;
            } while (i <= (data_length + 1));
            adjusted_string[j] = '\0';
            adjusted_length = (int) strlen(adjusted_string);
            adjustment_size = adjusted_length - data_length;

            /* Add padding */
            remainder = adjusted_length % codeword_size;

            padbits = codeword_size - remainder;
            if (padbits == codeword_size) {
                padbits = 0;
            }

            for (i = 0; i < padbits; i++) {
                strcat(adjusted_string, "1");
            }
            adjusted_length = (int) strlen(adjusted_string);

            count = 0;
            for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
                if (adjusted_string[i] == '1') {
                    count++;
                }
            }
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
                }
            }
            adjusted_string[j] = binary_string[i];
            j++;
            i++;
        } while (i <= (data_length + 1));
        adjusted_string[j] = '\0';
        adjusted_length = strlen(adjusted_string);

        remainder = adjusted_length % codeword_size;

        padbits = codeword_size - remainder;
        if (padbits == codeword_size) {
            padbits = 0;
        }

        for (i = 0; i < padbits; i++) {
            strcat(adjusted_string, "1");
        }
        adjusted_length = strlen(adjusted_string);

        count = 0;
        for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
            if (adjusted_string[i] == '1') {
                count++;
            }
        }
        if (count == codeword_size) {
            adjusted_string[adjusted_length - 1] = '0';
        }

        /* Check if the data actually fits into the selected symbol size */
        if (compact) {
            data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
        } else {
            data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3);
        }

        if (adjusted_length > data_maxsize) {
            strcpy(symbol->errtxt, "Data too long for specified Aztec Code symbol size");
            return ZINT_ERROR_TOO_LONG;
        }

        if (debug) {
            printf("Codewords:\n");
            for (i = 0; i < (adjusted_length / codeword_size); i++) {
                for (j = 0; j < codeword_size; j++) {
                    printf("%c", adjusted_string[(i * codeword_size) + j]);
                }
                printf("\n");
            }
        }

    }

    if (reader && (layers > 22)) {
        strcpy(symbol->errtxt, "Data too long for reader initialisation symbol");
        return ZINT_ERROR_TOO_LONG;
    }

    data_blocks = adjusted_length / codeword_size;

    if (compact) {
        ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks;







|











|



















|
















|







1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
                }
            }
            adjusted_string[j] = binary_string[i];
            j++;
            i++;
        } while (i <= (data_length + 1));
        adjusted_string[j] = '\0';
        adjusted_length = (int) strlen(adjusted_string);

        remainder = adjusted_length % codeword_size;

        padbits = codeword_size - remainder;
        if (padbits == codeword_size) {
            padbits = 0;
        }

        for (i = 0; i < padbits; i++) {
            strcat(adjusted_string, "1");
        }
        adjusted_length = (int) strlen(adjusted_string);

        count = 0;
        for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
            if (adjusted_string[i] == '1') {
                count++;
            }
        }
        if (count == codeword_size) {
            adjusted_string[adjusted_length - 1] = '0';
        }

        /* Check if the data actually fits into the selected symbol size */
        if (compact) {
            data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
        } else {
            data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3);
        }

        if (adjusted_length > data_maxsize) {
            strcpy(symbol->errtxt, "Data too long for specified Aztec Code symbol size (E05)");
            return ZINT_ERROR_TOO_LONG;
        }

        if (debug) {
            printf("Codewords:\n");
            for (i = 0; i < (adjusted_length / codeword_size); i++) {
                for (j = 0; j < codeword_size; j++) {
                    printf("%c", adjusted_string[(i * codeword_size) + j]);
                }
                printf("\n");
            }
        }

    }

    if (reader && (layers > 22)) {
        strcpy(symbol->errtxt, "Data too long for reader initialisation symbol (E06)");
        return ZINT_ERROR_TOO_LONG;
    }

    data_blocks = adjusted_length / codeword_size;

    if (compact) {
        ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks;
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
        } else {
            if ((data_blocks - 1) & 0x20) {
                descriptor[2] = '1';
            } else {
                descriptor[2] = '0';
            }
        }
        if ((data_blocks - 1) & 0x10) {
            descriptor[3] = '1';
        } else {
            descriptor[3] = '0';
        }

        if ((data_blocks - 1) & 0x08) {
            descriptor[4] = '1';
        } else {
            descriptor[4] = '0';
        }
        if ((data_blocks - 1) & 0x04) {
            descriptor[5] = '1';
        } else {
            descriptor[5] = '0';
        }
        if ((data_blocks - 1) & 0x02) {
            descriptor[6] = '1';
        } else {
            descriptor[6] = '0';
        }
        if ((data_blocks - 1) & 0x01) {
            descriptor[7] = '1';
        } else {
            descriptor[7] = '0';
        }
        descriptor[8] = '\0';
        if (debug) printf("Mode Message = %s\n", descriptor);
    } else {
        /* The first 5 bits represent the number of layers minus 1 */

        if ((layers - 1) & 0x10) {
            descriptor[0] = '1';
        } else {
            descriptor[0] = '0';
        }
        if ((layers - 1) & 0x08) {
            descriptor[1] = '1';
        } else {
            descriptor[1] = '0';
        }
        if ((layers - 1) & 0x04) {
            descriptor[2] = '1';
        } else {
            descriptor[2] = '0';
        }
        if ((layers - 1) & 0x02) {
            descriptor[3] = '1';
        } else {
            descriptor[3] = '0';
        }
        if ((layers - 1) & 0x01) {
            descriptor[4] = '1';
        } else {
            descriptor[4] = '0';
        }
        /* The next 11 bits represent the number of data blocks minus 1 */
        if (reader) {
            descriptor[5] = '1';
        } else {
            if ((data_blocks - 1) & 0x400) {
                descriptor[5] = '1';
            } else {
                descriptor[5] = '0';
            }
        }
        if ((data_blocks - 1) & 0x200) {
            descriptor[6] = '1';
        } else {
            descriptor[6] = '0';
        }
        if ((data_blocks - 1) & 0x100) {
            descriptor[7] = '1';
        } else {
            descriptor[7] = '0';
        }
        if ((data_blocks - 1) & 0x80) {
            descriptor[8] = '1';
        } else {
            descriptor[8] = '0';
        }
        if ((data_blocks - 1) & 0x40) {
            descriptor[9] = '1';
        } else {
            descriptor[9] = '0';
        }
        if ((data_blocks - 1) & 0x20) {
            descriptor[10] = '1';
        } else {
            descriptor[10] = '0';
        }
        if ((data_blocks - 1) & 0x10) {
            descriptor[11] = '1';
        } else {
            descriptor[11] = '0';
        }
        if ((data_blocks - 1) & 0x08) {
            descriptor[12] = '1';
        } else {
            descriptor[12] = '0';
        }
        if ((data_blocks - 1) & 0x04) {
            descriptor[13] = '1';
        } else {
            descriptor[13] = '0';
        }
        if ((data_blocks - 1) & 0x02) {
            descriptor[14] = '1';
        } else {
            descriptor[14] = '0';
        }
        if ((data_blocks - 1) & 0x01) {
            descriptor[15] = '1';
        } else {
            descriptor[15] = '0';
        }
        descriptor[16] = '\0';
        if (debug) printf("Mode Message = %s\n", descriptor);
    }

    /* Split into 4-bit codewords */
    for (i = 0; i < 4; i++) {







<
<
<
<
|
>
|
|
|
|
|
<
<
<
<

<
<
<
<
|
<
<
<
<
<




>
|
|
|
|
|
<
<
<
<

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<










|
<
<
<
<
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1381
1382
1383
1384
1385
1386
1387




1388
1389
1390
1391
1392
1393
1394




1395




1396





1397
1398
1399
1400
1401
1402
1403
1404
1405
1406




1407




1408










1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419




1420
1421
1422
1423
1424







































1425
1426
1427
1428
1429
1430
1431
        } else {
            if ((data_blocks - 1) & 0x20) {
                descriptor[2] = '1';
            } else {
                descriptor[2] = '0';
            }
        }





        for (i = 3; i < 8; i++) {
            if ((data_blocks - 1) & (0x10 >> (i - 3))) {
                descriptor[i] = '1';
            } else {
                descriptor[i] = '0';
            }




        }










        descriptor[8] = '\0';
        if (debug) printf("Mode Message = %s\n", descriptor);
    } else {
        /* The first 5 bits represent the number of layers minus 1 */
        for (i = 0; i < 5; i++) {
            if ((layers - 1) & (0x10 >> i)) {
                descriptor[i] = '1';
            } else {
                descriptor[i] = '0';
            }




        }















        /* The next 11 bits represent the number of data blocks minus 1 */
        if (reader) {
            descriptor[5] = '1';
        } else {
            if ((data_blocks - 1) & 0x400) {
                descriptor[5] = '1';
            } else {
                descriptor[5] = '0';
            }
        }
        for (i = 6; i < 16; i++) {




            if ((data_blocks - 1) & (0x200 >> (i - 6))) {
                descriptor[i] = '1';
            } else {
                descriptor[i] = '0';
            }







































        }
        descriptor[16] = '\0';
        if (debug) printf("Mode Message = %s\n", descriptor);
    }

    /* Split into 4-bit codewords */
    for (i = 0; i < 4; i++) {
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
    int input_value, error_number, i, p, y, x;
    char binary_string[28];
    unsigned char data_codewords[3], ecc_codewords[6];

    error_number = 0;
    input_value = 0;
    if (length > 3) {
        strcpy(symbol->errtxt, "Input too large");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Invalid characters in input");
        return ZINT_ERROR_INVALID_DATA;
    }
    switch (length) {
        case 3: input_value = 100 * ctoi(source[0]);
            input_value += 10 * ctoi(source[1]);
            input_value += ctoi(source[2]);
            break;
        case 2: input_value = 10 * ctoi(source[0]);
            input_value += ctoi(source[1]);
            break;
        case 1: input_value = ctoi(source[0]);
            break;
    }

    if (input_value > 255) {
        strcpy(symbol->errtxt, "Input too large");
        return ZINT_ERROR_INVALID_DATA;
    }

    strcpy(binary_string, "");
    for (p = 0; p < 8; p++) {
        if (input_value & (0x80 >> p)) {
            strcat(binary_string, "1");







|




|















|







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
    int input_value, error_number, i, p, y, x;
    char binary_string[28];
    unsigned char data_codewords[3], ecc_codewords[6];

    error_number = 0;
    input_value = 0;
    if (length > 3) {
        strcpy(symbol->errtxt, "Input too large (E07)");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Invalid characters in input (E08)");
        return ZINT_ERROR_INVALID_DATA;
    }
    switch (length) {
        case 3: input_value = 100 * ctoi(source[0]);
            input_value += 10 * ctoi(source[1]);
            input_value += ctoi(source[2]);
            break;
        case 2: input_value = 10 * ctoi(source[0]);
            input_value += ctoi(source[1]);
            break;
        case 1: input_value = ctoi(source[0]);
            break;
    }

    if (input_value > 255) {
        strcpy(symbol->errtxt, "Input too large (E09)");
        return ZINT_ERROR_INVALID_DATA;
    }

    strcpy(binary_string, "");
    for (p = 0; p < 8; p++) {
        if (input_value & (0x80 >> p)) {
            strcat(binary_string, "1");
Changes to jni/zint/backend/aztec.h.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#define UPPER	1
#define LOWER	2
#define MIXED	4
#define PUNC	8
#define DIGIT	16
#define BINARY	32

static int AztecMap[22801];

static const int CompactAztecMap[] = {
    /* 27 x 27 data grid */
    609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459,
    607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458,
    605, 604, 409, 408, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 460, 461,
    603, 602, 407, 406, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 462, 463,
    601, 600, 405, 404, 241, 240, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 284, 285, 464, 465,







<
<







33
34
35
36
37
38
39


40
41
42
43
44
45
46
#define UPPER	1
#define LOWER	2
#define MIXED	4
#define PUNC	8
#define DIGIT	16
#define BINARY	32



static const int CompactAztecMap[] = {
    /* 27 x 27 data grid */
    609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459,
    607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458,
    605, 604, 409, 408, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 460, 461,
    603, 602, 407, 406, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 462, 463,
    601, 600, 405, 404, 241, 240, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 284, 285, 464, 465,
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

/* Problem characters are:
        300: Carriage Return (ASCII 13)
        301: Comma (ASCII 44)
        302: Full Stop (ASCII 46)
 */

static const char *hexbit[32] = {
    "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001",
    "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101",
    "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111"
};

static const char *pentbit[16] = {
    "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001",
    "1010", "1011", "1100", "1101", "1110", "1111"
};

static const char *tribit[8] = {
    "000", "001", "010", "011", "100", "101", "110", "111"
};







|





|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

/* Problem characters are:
        300: Carriage Return (ASCII 13)
        301: Comma (ASCII 44)
        302: Full Stop (ASCII 46)
 */

static const char *pentbit[32] = {
    "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001",
    "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101",
    "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111"
};

static const char *quadbit[16] = {
    "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001",
    "1010", "1011", "1100", "1101", "1110", "1111"
};

static const char *tribit[8] = {
    "000", "001", "010", "011", "100", "101", "110", "111"
};
Added jni/zint/backend/bmp.c.






























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* bmp.c - Handles output to Windows Bitmap file */

/*
    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "bmp.h"        /* Bitmap header structure */
#include <math.h>
#ifdef _MSC_VER
#include <io.h>
#include <fcntl.h>
#endif

#define SSET	"0123456789ABCDEF"

int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
    int i, row, column;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
    int row_size;
    unsigned int data_size;
    unsigned char *bitmap_file_start, *bmp_posn;
    char *bitmap;
    FILE *bmp_file;
    bitmap_file_header_t file_header;
    bitmap_info_header_t info_header;

    if (symbol->bitmap != NULL)
        free(symbol->bitmap);

    row_size = 4 * floor((24.0 * symbol->bitmap_width + 31) / 32);
    bitmap = (char *) malloc(row_size * symbol->bitmap_height);

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);

    /* Pixel Plotting */
    i = 0;
    for (row = 0; row < symbol->bitmap_height; row++) {
        for (column = 0; column < symbol->bitmap_width; column++) {
            i = (3 * column) + (row * row_size);
            switch (*(pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1)) + column)) {
                case '1':
                    bitmap[i] = fgblu;
                    bitmap[i + 1] = fggrn;
                    bitmap[i + 2] = fgred;
                    break;
                default:
                    bitmap[i] = bgblu;
                    bitmap[i + 1] = bggrn;
                    bitmap[i + 2] = bgred;
                    break;

            }
        }
    }

    data_size = symbol->bitmap_height * row_size;
    symbol->bitmap_byte_length = data_size;

    file_header.header_field = 0x4d42; // "BM"
    file_header.file_size = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t) + data_size;
    file_header.reserved = 0;
    file_header.data_offset = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t);

    info_header.header_size = sizeof (bitmap_info_header_t);
    info_header.width = symbol->bitmap_width;
    info_header.height = symbol->bitmap_height;
    info_header.colour_planes = 1;
    info_header.bits_per_pixel = 24;
    info_header.compression_method = 0; // BI_RGB
    info_header.image_size = 0;
    info_header.horiz_res = 0;
    info_header.vert_res = 0;
    info_header.colours = 0;
    info_header.important_colours = 0;

    bitmap_file_start = (unsigned char*) malloc(file_header.file_size);
    memset(bitmap_file_start, 0xff, file_header.file_size);

    bmp_posn = bitmap_file_start;
    memcpy(bitmap_file_start, &file_header, sizeof (bitmap_file_header_t));
    bmp_posn += sizeof (bitmap_file_header_t);
    memcpy(bmp_posn, &info_header, sizeof (bitmap_info_header_t));
    bmp_posn += sizeof (bitmap_info_header_t);
    memcpy(bmp_posn, bitmap, data_size);

    /* Open output file in binary mode */
    if ((symbol->output_options & BARCODE_STDOUT) != 0) {
#ifdef _MSC_VER
        if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
#endif
        bmp_file = stdout;
    } else {
        if (!(bmp_file = fopen(symbol->outfile, "wb"))) {
            strcpy(symbol->errtxt, "Can't open output file (F00)");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    fwrite(bitmap_file_start, file_header.file_size, 1, bmp_file);
    fclose(bmp_file);

    free(bitmap_file_start);
    free(bitmap);
    return 0;
}
Added jni/zint/backend/bmp.h.
























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*  bmp.h - header structure for Windows bitmap files

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#ifndef BMP_H
#define BMP_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#include <windows.h>
#include "stdint_msvc.h"
#else
#include <stdint.h>
#endif

#pragma pack (1)
    
    typedef struct bitmap_file_header {
        uint16_t header_field;
        uint32_t file_size;
        uint32_t reserved;
        uint32_t data_offset;
    } bitmap_file_header_t;

    typedef struct bitmap_info_header {
        uint32_t header_size;
        int32_t width;
        int32_t height;
        uint16_t colour_planes;
        uint16_t bits_per_pixel;
        uint32_t compression_method;
        uint32_t image_size;
        int32_t horiz_res;
        int32_t vert_res;
        uint32_t colours;
        uint32_t important_colours;
    } bitmap_info_header_t;
    
#pragma pack ()
    
#ifdef __cplusplus
}
#endif

#endif /* BMP_H */

Added jni/zint/backend/codablock.c.










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
/* codablock.c - Handles Codablock-F and Codablock-E */

/*
    libzint - the open source barcode library
    Copyright (C) 2016 Harald Oehlmann

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
 */

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "common.h"
#include "gs1.h"

#define uchar unsigned char

/* FTab C128 flags - may be added */
#define CodeA 1
#define CodeB 2
#define CodeC 4
#define CEnd 8
#define CShift 16
#define CFill 32
#define CodeFNC1 64
#define ZTNum (CodeA+CodeB+CodeC)
#define ZTFNC1 (CodeA+CodeB+CodeC+CodeFNC1)

/* ASCII-Extension for Codablock-F */
#define aFNC1 (uchar)(128)
#define aFNC2 (uchar)(129)
#define aFNC3 (uchar)(130)
#define aFNC4 (uchar)(131)
#define aCodeA (uchar)(132)
#define aCodeB (uchar)(133)
#define aCodeC (uchar)(134)
#define aShift (uchar)(135)

static const char *C128Table[107] = {
    /* Code 128 character encodation - Table 1 */
    "212222", "222122", "222221", "121223", "121322", "131222", "122213",
    "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222",
    "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222",
    "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323",
    "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133",
    "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113",
    "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111",
    "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214",
    "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112",
    "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112",
    "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311",
    "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232",
    "2331112"
};

/* Code F Analysing-Chart */
typedef struct sCharacterSetTable
{
    int CharacterSet;       /* Still possible character sets for actual*/
    int AFollowing;     /* Still following Characters in Charset A */
    int BFollowing;     /* Still following Characters in Charset B */
    int CFollowing;     /* Still following Characters in Charset C */
} CharacterSetTable;

/* Find the possible Code-128 Character sets for a character
 * The result is an or of CodeA,CodeB,CodeC,CodeFNC1 in dependency of the
 * possible Code 128 character sets.
 */
int GetPossibleCharacterSet(unsigned char C)
{
    if (C<='\x19')      /* Dec:31 */
        return CodeA;
    if (C>='0' && C<='9')
        return ZTNum;   /* ZTNum=CodeA+CodeB+CodeC */
    if (C==aFNC1)
        return ZTFNC1;  /* ZTFNC1=CodeA+CodeB+CodeC+CodeFNC1 */
    if (C>='\x60' && C<='\x7f')      /* 60 to 127 */
        return CodeB;
    return CodeA+CodeB;
}

/* Create a Table with the following information for each Data character:
 *  int CharacterSet    is an or of CodeA,CodeB,CodeC,CodeFNC1, in
 *          dependency which character set is applicable.
 *          (Result of GetPossibleCharacterSet)
 *  int AFollowing,BFollowing   The number of source characters you still may encode
 *          in this character set.
 *  int CFollowing  The number of characters encodable in CodeC if we
 *          start here.
 */
void CreateCharacterSetTable(CharacterSetTable T[], unsigned char *data, int dataLength)
{
    int charCur;
    int runChar;

    /* Treat the Data backwards */
    charCur=dataLength-1;
    T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]);
    T[charCur].AFollowing=((T[charCur].CharacterSet & CodeA)==0)?0:1;
    T[charCur].BFollowing=((T[charCur].CharacterSet & CodeB)==0)?0:1;
    T[charCur].CFollowing=0;

    for (charCur--;charCur>=0;charCur--)
    {
        T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]);
        T[charCur].AFollowing=
            ((T[charCur].CharacterSet & CodeA)==0)?0:T[charCur+1].AFollowing+1;
        T[charCur].BFollowing=
            ((T[charCur].CharacterSet & CodeB)==0)?0:T[charCur+1].BFollowing+1;
        T[charCur].CFollowing=0;

    }
    /* Find the CodeC-chains */
    for (charCur=0;charCur<dataLength;charCur++)
    {
        T[charCur].CFollowing=0;
        if ((T[charCur].CharacterSet & CodeC)!=0)
        {
            /* CodeC possible */
            runChar=charCur;
            do{
                /* Wether this is FNC1 wether next is */
                /* numeric */
                if (T[runChar].CharacterSet==ZTFNC1)
                    /* FNC1 */
                    ++(T[charCur].CFollowing);
                else
                {
                    ++runChar;
                    if (runChar>=dataLength)
                        break;
                    /* Only a Number may follow */
                    if (T[runChar].CharacterSet==ZTNum)
                        T[charCur].CFollowing+=2;
                    else
                        break;
                }
                ++runChar;
            } while (runChar<dataLength);
        }
    }
}

/* Find the amount of numerical characters in pairs which will fit in
 * one bundle into the line (up to here). This is calculated online because
 * it depends on the space in the line.
 */
int RemainingDigits(CharacterSetTable *T, int charCur,int emptyColumns)
{
    int digitCount;     /* Numerical digits fitting in the line */
    int runChar;
    runChar=charCur;
    digitCount=0;
    while(emptyColumns>0 && runChar<charCur+T[charCur].CFollowing)
    {
        if (T[runChar].CharacterSet!=ZTFNC1)
        {
            /* NOT FNC1 */
            digitCount+=2;
            runChar++;
        }
        runChar++;
        emptyColumns--;
    }
    return digitCount;
}

/* Find the Character distribution at a given column count.
 * If to many rows (>44) are requested the columns is extended.
 * A oneLigner may be choosen if shorter.
 * Parameters :
 *  T       Pointer on the Characters which fit in the row
 *          If a different count is calculated it is corrected
 *          in the callers workspace.
 *  pFillings   Output of filling characters
 *  pSet        Output of the character sets used, allocated by me.
 *  Data        The Data string to encode, exceptionnally not an out
 *  Return value    Resulting row count
 */

int Columns2Rows(CharacterSetTable *T, unsigned char *data, int dataLength,
        int * pRows, int * pUseColumns, int * pSet, int * pFillings)
{
    int useColumns;     /* Usable Characters per line */
    int fillings;       /* Number of filling characters */
    int rowsCur;
    int charCur;
    int runChar;
    int emptyColumns;   /* Number of codes still empty in line. */
    int emptyColumns2;  /* Alternative emptyColumns to compare */
    int fOneLiner;      /* Flag if One Liner */
    int CPaires;        /* Number of digit pairs which may fit in the line */
    int characterSetCur;        /* Current Character Set */

    useColumns=*pUseColumns;
    if (useColumns<3)
        useColumns=3;

    /* >>> Loop until rowsCur<44 */
    do {
        memset(pSet,0,dataLength*sizeof(int));
        charCur=0;
        rowsCur=0;
        fOneLiner=1;        /* First try one-Liner */

        /* >>> Line and OneLiner-try Loop */
        do{
            /* >> Start Character */
            emptyColumns=useColumns;    /* Remained place in Line */
            if (fOneLiner)
                emptyColumns+=2;

            /* >>Choose in Set A or B */
            /* (C is changed as an option later on) */

            pSet[charCur]=characterSetCur=
                (T[charCur].AFollowing > T[charCur].BFollowing)
                ? CodeA : CodeB;

            /* >> Test on Numeric Mode C */
            CPaires=RemainingDigits(T,charCur, emptyColumns);
            if (CPaires>=4)
            {
                /* 4 Digits in Numeric compression ->OK */
                /* > May an odd start find more ? */
                /* Skip leading <FNC1>'s */
                /* Typical structure : <FNC1><FNC1>12... */
                /* Test if numeric after one isn't better.*/
                runChar=charCur;
                emptyColumns2=emptyColumns;
                while (T[runChar].CharacterSet==ZTFNC1)
                {
                    ++runChar;
                    --emptyColumns2;
                }
                if (CPaires>=RemainingDigits(T,runChar+1,emptyColumns2-1))
                {
                    /* Start odd is not better */
                    /* We start in C */
                    pSet[charCur]=characterSetCur=CodeC;
                    /* Inkrement charCur */
                    if (T[charCur].CharacterSet!=ZTFNC1)
                        ++charCur;      /* 2 Num.Digits */
                }
            }
            ++charCur;
            --emptyColumns;

            /* >> Following characters */
            while(emptyColumns>0 && charCur<dataLength)
            {
                switch(characterSetCur){
                case CodeA:
                case CodeB:
                    /* >> Check switching to CodeC */
                    /* Switch if :
                     *  - Character not FNC1
                     *  - 4 real Digits will fit in line
                     *  - an odd Start will not be better
                     */
                    if (T[charCur].CharacterSet==ZTNum
                        && (CPaires=RemainingDigits(T,charCur, emptyColumns-1))>=4
                        && CPaires > RemainingDigits(T,charCur+1,emptyColumns-2))
                    {
                        /* > Change to C */
                        pSet[charCur]=characterSetCur=CodeC;
                        charCur+=2; /* 2 Digit */
                        emptyColumns-=2; /* <SwitchC>12 */
                    } else if (characterSetCur==CodeA)
                    {
                        if(T[charCur].AFollowing==0)
                        {
                            /* Must change to B */
                            if (emptyColumns==1)
                            {
                                /* Can't switch: */
                                pSet[charCur-1]|=CEnd+CFill;
                                emptyColumns=0;
                            }else{
                                /* <Shift> or <switchB>? */
                                pSet[charCur]|=(T[charCur].BFollowing==1)?CShift:CodeB;
                                emptyColumns-=2;
                                ++charCur;
                            }
                        }else{
                            --emptyColumns;
                            ++charCur;
                        }
                    } else { /* Last possibility : CodeB */
                        if(T[charCur].BFollowing==0)
                        {
                            /* Must change to A */
                            if (emptyColumns==1)
                            {
                                /* Can't switch: */
                                pSet[charCur-1]|=CEnd+CFill;
                                emptyColumns=0;
                            } else {
                                /* <Shift> or <switchA>? */
                                pSet[charCur]|=(T[charCur].AFollowing==1)?CShift:CodeA;
                                emptyColumns-=2;
                                ++charCur;
                            }
                        }else{
                            --emptyColumns;
                            ++charCur;
                        }
                    }
                    break;
                case CodeC:
                    if(T[charCur].CFollowing>0)
                    {
                        charCur+=(T[charCur].CharacterSet==ZTFNC1)?1:2;
                        emptyColumns--;
                    }else{
                        /* Must change to A or B */
                        if (emptyColumns==1)
                        {
                            /* Can't switch: */
                            pSet[charCur-1]|=CEnd+CFill;
                            emptyColumns=0;
                        }else{
                            /*<SwitchA> or <switchA>?*/
                            characterSetCur=pSet[charCur]=
                                (T[charCur].AFollowing > T[charCur].BFollowing)
                                ?CodeA:CodeB;
                            emptyColumns-=2;
                            ++charCur;
                        }
                    }
                    break;
                } /* switch */
            } /* while */

            /* > End of Codeline */
            pSet[charCur-1]|=CEnd;
            ++rowsCur;
            if ( fOneLiner)
            {
                if (charCur<dataLength)
                {
                    /* One line not sufficiant */
                    fOneLiner=0;
                    /* Reset and Start again */
                    charCur=0;
                    rowsCur=0;
                    memset(pSet,0,dataLength*sizeof(int));
                }else{
                    /* Calculate real Length of OneLiner */
                    /* This is -2 BASED !!! */
                    useColumns-=emptyColumns;
                }
            }
        } while (charCur<dataLength); /* <= Data.Len-1 */

        /* Place check characters C1,C2 */
        if (fOneLiner)
            fillings=0;
        else{
            switch (emptyColumns) {
            case 1:
                pSet[charCur-1]|=CFill;
                /* Glide in following block without break */
            case 0:
                ++rowsCur;
                fillings=useColumns-2+emptyColumns;
                break;
            case 2:
                fillings=0;
                break;
            default:
                pSet[charCur-1]|=CFill;
                fillings=emptyColumns-2;
            }
        }

        if (rowsCur>44) {
            ++useColumns;
            if (useColumns > 62) {
                return ZINT_ERROR_TOO_LONG;
            }
        }
    } while(rowsCur>44);
    #ifdef _DEBUG
        printf("  -> out: rowsCur <%i>, useColumns <%i>, fillings <%i>\n",rowsCur,useColumns,fillings);
    #endif
    *pUseColumns=useColumns;
    *pRows=rowsCur;
    *pFillings=fillings;
    return 0;
}
/* Find columns if row count is given.
 */
int Rows2Columns(CharacterSetTable *T, unsigned char *data, int dataLength,
        int * pRows, int * pUseColumns, int * pSet, int * pFillings)
{
    int errorCur;
    int rowsCur;
    int rowsRequested;  /* Number of requested rows */
    int backupRows = 0;
    int fillings;
    int backupFillings = 0;
    int useColumns;
    int testColumns;    /* To enter into Width2Rows */
    int backupColumns = 0;
    int fBackupOk = 0;      /* The memorysed set is o.k. */
    int testListSize = 0;
    int pTestList[62];
#ifndef _MSC_VER
    int *pBackupSet[dataLength];
#else
    int *pBackupSet = (int *)_alloca(dataLength*sizeof(int));
#endif

    rowsRequested=*pRows;

    #ifdef _DEBUG
        fprintf(stderr,"Optimizer : Searching <%i> rows\n",rowsRequested);
    #endif

    if (rowsRequested==1)
        /* OneLiners are self-calibrating */
        testColumns=32767;
    else {
        /* First guess */
        testColumns=dataLength/rowsRequested;
        if (testColumns > 62)
            testColumns = 62;
        else if (testColumns < 1)
            testColumns = 1;
    }

    for (;;) {
        pTestList[testListSize] = testColumns;
        testListSize++;
        useColumns=testColumns; /* Make a copy because it may be modified */
        errorCur = Columns2Rows(T, data, dataLength, &rowsCur, &useColumns, pSet, &fillings);
        if (errorCur != 0)
            return errorCur;
        if (rowsCur<=rowsRequested) {
            /* Less or exactly line number found */
            /* check if column count below already tested or Count = 1*/
            int fInTestList = (rowsCur == 1 || testColumns == 1);
            int posCur;
            for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
                if ( pTestList[posCur] == testColumns-1 )
                    fInTestList = 1;
            }
            if (fInTestList) {
                /* >> Smaller Width already tested
                 * if rowsCur=rowsRequested->Exit
                 * if rowsCur<rowsRequested and fillings>0
                 * -> New search for rowsRequested:=rowsCur
                 */
                if ( rowsCur == rowsRequested || fillings == 0 || testColumns == 1 ) {
                    /* Exit with actual */
                    *pFillings=fillings;
                    *pRows=rowsCur;
                    *pUseColumns = useColumns;
                    return 0;
                }
                /* Search again for smaller Line number */
                rowsRequested=rowsCur;
                pTestList[0] = testColumns;
                testListSize = 1;
            }
            /* > Test more rows (shorter CDB) */
            fBackupOk=(rowsCur==rowsRequested);
            memcpy(pBackupSet,pSet,dataLength*sizeof(int));
            backupFillings=fillings;
            backupColumns=useColumns;
            backupRows=rowsCur;
            --testColumns;
        } else {
            /* > To many rows */
            int fInTestList = fBackupOk;
            int posCur;
            for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
                if ( pTestList[posCur] == testColumns+1 )
                    fInTestList = 1;
            }
            if (fInTestList) {
                /* The next less-rows (larger) code was
                 * already tested. So give the larger
                 * back.
                 */
                memcpy(pSet,pBackupSet,dataLength*sizeof(int));
                *pFillings=backupFillings;
                *pRows=backupRows;
                *pUseColumns=backupColumns;
                return 0;
            }
            /* > Test less rows (longer code) */
            backupRows=rowsCur;
            memcpy(pBackupSet,pSet,dataLength*sizeof(int));
            backupFillings=fillings;
            backupColumns=useColumns;
            fBackupOk=0;
            ++testColumns;
        }
    }
}

/* Print a character in character set A
 */
void A2C128_A(uchar **ppOutPos,uchar c)
{
    uchar * pOutPos = *ppOutPos;
    switch(c){
    case aCodeB: *pOutPos=100; break;
    case aFNC4: *pOutPos=101; break;
    case aFNC1: *pOutPos=102; break;
    case aFNC2: *pOutPos=97; break;
    case aFNC3: *pOutPos=96; break;
    case aCodeC: *pOutPos=99; break;
    case aShift: *pOutPos=98; break;
    default:
        /* +++ HaO 13.11.98 c>' ' && c < '\x1F' corrected */
        if(c>=' ' && c<='_')
            *pOutPos=(uchar)(c-' ');
        else
            *pOutPos=(uchar)(c+64);
        break;
    }
    (*ppOutPos)++;
}
/* Output c in Set B
 */
void A2C128_B(uchar **ppOutPos,uchar c)
{
    uchar * pOutPos = *ppOutPos;
    switch(c){
    case aFNC1: *pOutPos=102; break;
    case aFNC2: *pOutPos=97; break;
    case aFNC3: *pOutPos=96; break;
    case aFNC4: *pOutPos=100; break;
    case aCodeA: *pOutPos=101; break;
    case aCodeC: *pOutPos=99; break;
    case aShift: *pOutPos=98; break;
    default: *pOutPos=(uchar)(c-' '); break;
    }
    ++(*ppOutPos);
}
/* Output c1, c2 in Set C
 */
void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2)
{
    uchar * pOutPos = *ppOutPos;
    switch(c1){
    case aFNC1: *pOutPos=102; break;
    case aCodeB: *pOutPos=100; break;
    case aCodeA: *pOutPos=101; break;
    default: *pOutPos=(char)(10 * (c1- '0') + (c2 - '0'));break;
    }
    (*ppOutPos)++;
}
/* Output a character in Characterset
 */
void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2)
{
    if (CharacterSet==CodeA)
        A2C128_A(ppOutPos,c1);
    else if(CharacterSet==CodeB)
        A2C128_B(ppOutPos,c1);
    else
        A2C128_C(ppOutPos,c1,c2);
}
/* XLate Table A of Codablock-F Specification and call output
 */
void SumASCII(uchar **ppOutPos, int Sum, int CharacterSet)
{
    switch (CharacterSet){
    case CodeA:
        A2C128_A(ppOutPos, (uchar)Sum);
        break;
    case CodeB:
        if (Sum<=31)
            A2C128_B(ppOutPos, (uchar)(Sum+96));
        else if(Sum<=47)
            A2C128_B(ppOutPos, (uchar)Sum);
        else
            A2C128_B(ppOutPos, (uchar)(Sum+10));
        break;
    case CodeC:
        A2C128_C(ppOutPos
            ,(char)(Sum/10+'0') ,(uchar)(Sum%10+'0'));
        break;
    }
}

/* Main function called by zint framework
 */
int codablock(struct zint_symbol *symbol, unsigned char source[], int length) {
    int charCur;
    int dataLength;
    int Error;
    int rows, columns, useColumns;
    int fillings;
    int Sum1,Sum2;
    uchar * pOutPos;
    int rowCur;
    int characterSetCur;
    int emptyColumns;
        char dest[1000];
        int r, c;
#ifdef _MSC_VER
    CharacterSetTable *T;
    unsigned char *data;
    int *pSet;
    uchar * pOutput;
#endif

    /* Parameter check */
    /* option1: rows 0: automatic, 1..44 */
    rows = symbol->option_1;
    if (rows > 44) {
        strcpy(symbol->errtxt, "Row parameter not in 0..44 (D10)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    /* option_2: (usable data) columns: 0: automatic, 6..66 */
    columns = symbol->option_2;
    if ( ! (columns <= 0 || (columns >= 6 && columns <=66)) ) {
        strcpy(symbol->errtxt, "Columns parameter not in 0,6..66 (D11)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    /* GS1 not implemented */
    if  (symbol->input_mode == GS1_MODE) {
        strcpy(symbol->errtxt, "GS1 mode not supported (D12)");
        return ZINT_ERROR_INVALID_OPTION;
    }
#ifndef _MSC_VER
    unsigned char data[length*2+1];
#else
    data = (unsigned char *) _alloca(length * 2+1);
#endif

    dataLength = 0;
    if (symbol->output_options & READER_INIT) {
        data[dataLength] = aFNC3;
        dataLength++;
    }
    /* Replace all Codes>127 with <fnc4>Code-128 */
    for (charCur=0;charCur<length;charCur++) {
        if (source[charCur]>127)
        {
            data[dataLength] = aFNC4;
            dataLength++;
            data[dataLength] = (unsigned char)(source[charCur]&127);
        } else
            data[dataLength] = source[charCur];
        dataLength++;
    }

    /* Build character set table */
#ifndef _MSC_VER
    CharacterSetTable T[dataLength];
    int pSet[dataLength];
#else
    T=(CharacterSetTable *)_alloca(dataLength*sizeof(CharacterSetTable));
    pSet = (int *)_alloca(dataLength*sizeof(int));
#endif
    CreateCharacterSetTable(T,data,dataLength);

    /* Find final row and column count */
    /* nor row nor column count given */
    if ( rows <= 0 && columns <= 5 ) {
        /* Use Code128 until reasonable size */
        if (dataLength < 9) {
            rows = 1;
        } else {
            /* use 1/1 aspect/ratio Codablock */
            columns = ((int)floor(sqrt(1.0*dataLength))+5);
            if (columns > 64)
                columns = 64;
                #ifdef _DEBUG
                printf("Auto column count for %d characters:%d\n",dataLength,columns);
                #endif
        }
    }
    /* There are 5 Codewords for Organisation Start(2),row(1),CheckSum,Stop */
    useColumns = columns - 5;
    if ( rows > 0 ) {
        /* row count given */
        Error=Rows2Columns(T,data,dataLength,&rows,&useColumns,pSet,&fillings);
    } else {
        /* column count given */
        Error=Columns2Rows(T,data,dataLength,&rows,&useColumns,pSet,&fillings);
    }
    if (Error != 0) {
        strcpy(symbol->errtxt, "data string to long (D13)");
        return Error;
    }
    /* Checksum */
    Sum1=Sum2=0;
    if (rows>1)
    {
        int charCur;
        for (charCur=0 ; charCur<dataLength ; charCur++) {
            Sum1=(Sum1 + (charCur%86+1)*data[charCur])%86;
            Sum2=(Sum2 + (charCur%86)*data[charCur])%86;
        }
    }

    #ifdef _DEBUG
    {   /* start a new level of local variables */
        int DPos;
        printf("\nData:");
        for (DPos=0 ; DPos< dataLength ; DPos++)
            fputc(data[DPos],stdout);

        printf("\n Set:");
        for (DPos=0 ; DPos< dataLength ; DPos++) {
            switch (pSet[DPos]&(CodeA+CodeB+CodeC)) {
            case CodeA: fputc('A',stdout); break;
            case CodeB: fputc('B',stdout); break;
            case CodeC: fputc('C',stdout); break;
            default: fputc('.',stdout); break;
            }
        }
        printf("\nFNC1:");
        for (DPos=0 ; DPos< dataLength ; DPos++)
            fputc((pSet[DPos]&CodeFNC1)==0?'.':'X',stdout);
        printf("\n END:");
        for (DPos=0 ; DPos< dataLength ; DPos++)
            fputc((pSet[DPos]&CEnd)==0?'.':'X',stdout);
        printf("\nShif:");
        for (DPos=0 ; DPos< dataLength ; DPos++)
            fputc((pSet[DPos]&CShift)==0?'.':'X',stdout);
        printf("\nFILL:");
        for (DPos=0 ; DPos< dataLength ; DPos++)
            fputc((pSet[DPos]&CFill)==0?'.':'X',stdout);
        fputc('\n',stdout);
    }
    #endif

    columns = useColumns + 5;

    /* >>> Build C128 code numbers */
    /* The C128 column count contains Start (2CW), Row ID, Checksum, Stop */
#ifndef _MSC_VER
    uchar pOutput[columns * rows];
#else
    pOutput = (unsigned char *)_alloca(columns * rows * sizeof(char));
#endif
    pOutPos = pOutput;
    charCur=0;
    /* >> Loop over rows */
    for (rowCur=0 ; rowCur<rows ; rowCur++) {
        if (charCur>=dataLength)
        {
            /* >> Empty line with StartCCodeBCodeC */
            characterSetCur=CodeC;
            /* CDB Start C*/
            *pOutPos='\x67';
            pOutPos++;
            *pOutPos='\x63';
            pOutPos++;
            SumASCII(&pOutPos,rowCur+42,CodeC);
            emptyColumns=useColumns-2;
            while (emptyColumns>0)
            {
                if(characterSetCur==CodeC)
                {
                    A2C128_C(&pOutPos,aCodeB,'\0');
                    characterSetCur=CodeB;
                }else{
                    A2C128_B(&pOutPos,aCodeC);
                    characterSetCur=CodeC;
                }
                --emptyColumns;
            }
        }else{
            /* >> Normal Line */
            /* > Startcode */
            switch (pSet[charCur] & (CodeA+CodeB+CodeC)){
            case CodeA:
                *pOutPos = '\x67';
                pOutPos++;
                if (rows>1) {
                    *pOutPos = '\x62';
                    pOutPos++;
                }
                characterSetCur=CodeA;
                break;
            case CodeB:
                if (rows==1) {
                    *pOutPos = '\x68';
                    pOutPos++;
                } else {
                    *pOutPos = '\x67';
                    pOutPos++;
                    *pOutPos = '\x64';
                    pOutPos++;
                }
                characterSetCur=CodeB;
                break;
            case CodeC:
            default:
                if (rows==1) {
                    *pOutPos = '\x69';
                    pOutPos++;
                } else {
                    *pOutPos = '\x67';
                    pOutPos++;
                    *pOutPos = '\x63';
                    pOutPos++;
                }
                characterSetCur=CodeC;
                break;
            }
            if (rows>1)
            {
                /* > Set F1 */
                /* In first line : # of rows */
                /* In Case of CodeA we shifted to CodeB */
                SumASCII(&pOutPos
                    ,(rowCur==0)?rows-2:rowCur+42
                    ,(characterSetCur==CodeA)?CodeB:characterSetCur
                );
            }
            /* >>> Data */
            emptyColumns=useColumns;
            /* +++ One liner don't have start/stop code */
            if (rows == 1)
                emptyColumns +=2;
            /* >> Character loop */
            while (emptyColumns>0)
            {
                /* ? Change character set */
                /* not at first possition (It was then the start set) */
                /* +++ special case for one-ligner */
                if (emptyColumns<useColumns || (rows == 1 && charCur!=0) )
                {
                    if ((pSet[charCur]&CodeA)!=0)
                    {
                        /* Change to A */
                        ASCIIZ128(&pOutPos,characterSetCur,aCodeA,'\0');
                        --emptyColumns;
                        characterSetCur=CodeA;
                    } else if ((pSet[charCur]&CodeB)!=0)
                    {
                        /* Change to B */
                        ASCIIZ128(&pOutPos,characterSetCur,aCodeB,'\0');
                        --emptyColumns;
                        characterSetCur=CodeB;
                    } else if ((pSet[charCur]&CodeC)!=0)
                    {
                        /* Change to C */
                        ASCIIZ128(&pOutPos,characterSetCur,aCodeC,'\0');
                        --emptyColumns;
                        characterSetCur=CodeC;
                    }
                }
                if ((pSet[charCur]&CodeA)!=0)
                {
                    /* >> Shift it and put out the shifted character */
                    ASCIIZ128(&pOutPos,characterSetCur,aShift,'\0');
                    emptyColumns-=2;
                    characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB;
                    ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0');
                    characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB;
                }else{
                    /* Normal Character */
                    if (characterSetCur==CodeC)
                    {
                        if (data[charCur]==aFNC1)
                            A2C128_C(&pOutPos,aFNC1,'\0');
                        else
                        {
                            A2C128_C(&pOutPos,data[charCur],data[charCur+1]);
                            ++charCur;
                            /* We need this here to get the good index */
                            /* for the termination flags in Set. */
                        }
                    }else
                        ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0');
                    --emptyColumns;
                }
                /* >> End Criteria */
                if ((pSet[charCur] & CFill)!=0)
                {
                    /* Fill Line but leave space for checks in last line */
                    if(rowCur==rows-1 && emptyColumns>=2)
                        emptyColumns-=2;
                    while(emptyColumns>0)
                    {
                        switch(characterSetCur){
                        case CodeC:
                            A2C128_C(&pOutPos,aCodeB,'\0');
                            characterSetCur=CodeB;
                            break;
                        case CodeB:
                            A2C128_B(&pOutPos,aCodeC);
                            characterSetCur=CodeC;
                            break;
                        case CodeA:
                            A2C128_A(&pOutPos,aCodeC);
                            characterSetCur=CodeC;
                            break;
                        }
                        --emptyColumns;
                    }
                }
                if ((pSet[charCur] & CEnd)!=0)
                    emptyColumns=0;
                ++charCur;
            } /* Loop over characters */
        } /* if filling-Line / normal */

        /* Add checksum in last line */
        if(rows>1 && rowCur==rows-1)
        {
            SumASCII(&pOutPos,Sum1,characterSetCur);
            SumASCII(&pOutPos,Sum2,characterSetCur);
        }
        /* Add Code 128 checksum */
        {
            int Sum=0;
            int Pos=0;
            for ( ; Pos < useColumns+3 ; Pos++)
            {
                Sum = (Sum +
                    ((Pos==0?1:Pos) * pOutput[columns*rowCur+Pos]) % 103
                    ) % 103;
            }
            *pOutPos=(uchar)Sum;
            pOutPos++;
        }
        /* Add end character */
        *pOutPos=106;
        pOutPos++;
    } /* End Lineloop */

    #ifdef _DEBUG
        /* Dump the output to the screen
         */
        printf("\nCode 128 Code Numbers:\n");
        {   /* start a new level of local variables */
            int DPos, DPos2;
            for (DPos=0 ; DPos< rows ; DPos++)
            {
                for (DPos2=0 ; DPos2 < columns ; DPos2++)
                {
                    printf("%3d ",(int)(pOutput[DPos*columns+DPos2]));
                }
                printf("\n");
            }
        }
        printf("rows=%i columns=%i fillings=%i\n", rows, columns, fillings);
    #endif

    /* Paint the C128 patterns */
    for (r = 0; r < rows; r++) {
        strcpy(dest, "");
        for(c = 0; c < columns; c++) {
            strcat(dest, C128Table[pOutput[r * columns + c]]);
        }
        expand(symbol, dest);
        symbol->row_height[r] = 10;
    }
    
    if (!(symbol->output_options & BARCODE_BIND)) {
        symbol->output_options += BARCODE_BIND;
    }
        
    if (symbol->border_width < 2) {
        symbol->border_width = 2;
    }
    return 0;
}
Changes to jni/zint/backend/code.c.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

    unsigned int i;
    int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
    int weight[128], error_number;
    char dest[1024]; /* 6 +  121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/
    char checkstr[3];

    error_number = 0;

    if (length > 121) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SODIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    c_weight = 1;
    c_count = 0;
    k_weight = 1;
    k_count = 0;








<
<

|




|







108
109
110
111
112
113
114


115
116
117
118
119
120
121
122
123
124
125
126
127
128

    unsigned int i;
    int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
    int weight[128], error_number;
    char dest[1024]; /* 6 +  121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/
    char checkstr[3];



    if (length > 121) {
        strcpy(symbol->errtxt, "Input too long (C20)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SODIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C21)");
        return error_number;
    }
    c_weight = 1;
    c_count = 0;
    k_weight = 1;
    k_count = 0;

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

    ustrcpy(symbol->text, source);
    strcat((char*) symbol->text, checkstr);
    return error_number;
}

/* Code 39 */
int c39(struct zint_symbol *symbol, unsigned char source[], int length) {
    unsigned int i;
    unsigned int counter;
    char check_digit;
    int error_number;
    char dest[775];
    char localstr[2] = {0};

    error_number = 0;
    counter = 0;

    if ((symbol->option_2 < 0) || (symbol->option_2 > 1)) {
        symbol->option_2 = 0;
    }

    if ((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    } else if (length > 74) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(SILVER, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* Start character */
    strcpy(dest, "1211212111");

    for (i = 0; i < (unsigned int) length; i++) {







|







<







|


|





|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

    ustrcpy(symbol->text, source);
    strcat((char*) symbol->text, checkstr);
    return error_number;
}

/* Code 39 */
int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
    unsigned int i;
    unsigned int counter;
    char check_digit;
    int error_number;
    char dest[775];
    char localstr[2] = {0};


    counter = 0;

    if ((symbol->option_2 < 0) || (symbol->option_2 > 1)) {
        symbol->option_2 = 0;
    }

    if ((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) {
        strcpy(symbol->errtxt, "Input too long (C22)");
        return ZINT_ERROR_TOO_LONG;
    } else if (length > 74) {
        strcpy(symbol->errtxt, "Input too long (C23)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(SILVER, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C24)");
        return error_number;
    }

    /* Start character */
    strcpy(dest, "1211212111");

    for (i = 0; i < (unsigned int) length; i++) {
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    }

    /* Stop character */
    strcat(dest, "121121211");

    if ((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) {
        /* LOGMARS uses wider 'wide' bars than normal Code 39 */
        counter = strlen(dest);
        for (i = 0; i < counter; i++) {
            if (dest[i] == '2') {
                dest[i] = '3';
            }
        }
    }








|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    }

    /* Stop character */
    strcat(dest, "121121211");

    if ((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) {
        /* LOGMARS uses wider 'wide' bars than normal Code 39 */
        counter = (unsigned int) strlen(dest);
        for (i = 0; i < counter; i++) {
            if (dest[i] == '2') {
                dest[i] = '3';
            }
        }
    }

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/* Pharmazentral Nummer (PZN) */
int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number, zeroes;
    unsigned int count, check_digit;
    char localstr[10];

    error_number = 0;

    count = 0;
    if (length > 6) {
        strcpy(symbol->errtxt, "Input wrong length");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    localstr[0] = '-';
    zeroes = 6 - length + 1;
    for (i = 1; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);

    for (i = 1; i < 7; i++) {
        count += (i + 1) * ctoi(localstr[i]);
    }

    check_digit = count % 11;
    if (check_digit == 11) {
        check_digit = 0;
    }
    localstr[7] = itoc(check_digit);
    localstr[8] = '\0';
    if (localstr[7] == 'A') {
        strcpy(symbol->errtxt, "Invalid PZN Data");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = c39(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char *) "PZN");
    strcat((char*) symbol->text, localstr);
    return error_number;
}

/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
int ec39(struct zint_symbol *symbol, unsigned char source[], int length) {

    unsigned char buffer[150] = {0};
    unsigned int i;
    int error_number;

    error_number = 0;

    if (length > 74) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Creates a buffer string and places control characters into it */
    for (i = 0; i < (unsigned int) length; i++) {
        if (source[i] > 127) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat((char*) buffer, EC39Ctrl[source[i]]);
    }

    /* Then sends the buffer to the C39 function */
    error_number = c39(symbol, buffer, ustrlen(buffer));







<
<


|




|




















|















<
<

|







|







291
292
293
294
295
296
297


298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341


342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/* Pharmazentral Nummer (PZN) */
int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number, zeroes;
    unsigned int count, check_digit;
    char localstr[10];



    count = 0;
    if (length > 6) {
        strcpy(symbol->errtxt, "Input wrong length (C25)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C26)");
        return error_number;
    }

    localstr[0] = '-';
    zeroes = 6 - length + 1;
    for (i = 1; i < zeroes; i++)
        localstr[i] = '0';
    strcpy(localstr + zeroes, (char *) source);

    for (i = 1; i < 7; i++) {
        count += (i + 1) * ctoi(localstr[i]);
    }

    check_digit = count % 11;
    if (check_digit == 11) {
        check_digit = 0;
    }
    localstr[7] = itoc(check_digit);
    localstr[8] = '\0';
    if (localstr[7] == 'A') {
        strcpy(symbol->errtxt, "Invalid PZN Data (C27)");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = c39(symbol, (unsigned char *) localstr, strlen(localstr));
    ustrcpy(symbol->text, (unsigned char *) "PZN");
    strcat((char*) symbol->text, localstr);
    return error_number;
}

/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
int ec39(struct zint_symbol *symbol, unsigned char source[], int length) {

    unsigned char buffer[150] = {0};
    unsigned int i;
    int error_number;



    if (length > 74) {
        strcpy(symbol->errtxt, "Input too long (C28)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Creates a buffer string and places control characters into it */
    for (i = 0; i < (unsigned int) length; i++) {
        if (source[i] > 127) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data (C29)");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat((char*) buffer, EC39Ctrl[source[i]]);
    }

    /* Then sends the buffer to the C39 function */
    error_number = c39(symbol, buffer, ustrlen(buffer));
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
    char dest[670];
    char set_copy[] = SILVER;

    error_number = 0;
    strcpy(buffer, "");

    if (length > 107) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Message Content */
    for (i = 0; i < length; i++) {
        if (source[i] > 127) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat(buffer, C93Ctrl[source[i]]);
        symbol->text[i] = source[i] ? source[i] : ' ';
    }

    /* Now we can check the true length of the barcode */
    h = strlen(buffer);
    if (h > 107) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    for (i = 0; i < h; i++) {
        values[i] = posn(SILVER, buffer[i]);
    }








|







|







|

|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
    char dest[670];
    char set_copy[] = SILVER;

    error_number = 0;
    strcpy(buffer, "");

    if (length > 107) {
        strcpy(symbol->errtxt, "Input too long (C2A)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Message Content */
    for (i = 0; i < length; i++) {
        if (source[i] > 127) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data (C2B)");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat(buffer, C93Ctrl[source[i]]);
        symbol->text[i] = source[i] ? source[i] : ' ';
    }

    /* Now we can check the true length of the barcode */
    h = (int) strlen(buffer);
    if (h > 107) {
        strcpy(symbol->errtxt, "Input too long (C2C)");
        return ZINT_ERROR_TOO_LONG;
    }

    for (i = 0; i < h; i++) {
        values[i] = posn(SILVER, buffer[i]);
    }

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    int channels, i;
    int error_number = 0, range = 0, zeroes;
    char hrt[9];

    target_value = 0;

    if (length > 7) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
        channels = 0;
    } else {
        channels = symbol->option_2;







|




|







510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    int channels, i;
    int error_number = 0, range = 0, zeroes;
    char hrt[9];

    target_value = 0;

    if (length > 7) {
        strcpy(symbol->errtxt, "Input too long (C2D)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C2E)");
        return error_number;
    }

    if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
        channels = 0;
    } else {
        channels = symbol->option_2;
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
            break;
        case 8: if (target_value > 7742862) {
                range = 1;
            }
            break;
    }
    if (range) {
        strcpy(symbol->errtxt, "Value out of range");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < 11; i++) {
        B[i] = 0;
        S[i] = 0;
    }







|







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
            break;
        case 8: if (target_value > 7742862) {
                range = 1;
            }
            break;
    }
    if (range) {
        strcpy(symbol->errtxt, "Value out of range (C2F)");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < 11; i++) {
        B[i] = 0;
        S[i] = 0;
    }
Changes to jni/zint/backend/code1.c.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "common.h"
#include "code1.h"
#include "reedsol.h"
#include "large.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif

void horiz(struct zint_symbol *symbol, int row_no, int full) {
    int i;

    if (full) {
        for (i = 0; i < symbol->width; i++) {
            set_module(symbol, row_no, i);







<
<
<
<
<







33
34
35
36
37
38
39





40
41
42
43
44
45
46
#include "common.h"
#include "code1.h"
#include "reedsol.h"
#include "large.h"
#include <stdio.h>
#include <string.h>
#include <math.h>






void horiz(struct zint_symbol *symbol, int row_no, int full) {
    int i;

    if (full) {
        for (i = 0; i < symbol->width; i++) {
            set_module(symbol, row_no, i);
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    if (source[position + i - 1] == '>') {
        return 1;
    }

    return 0;
}

int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) {
    float ascii_count, c40_count, text_count, edi_count, byte_count;
    char reduced_char;
    int done, best_scheme, best_count, sp;

    /* Step J */
    if (current_mode == C1_ASCII) {
        ascii_count = 0.0;







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    if (source[position + i - 1] == '>') {
        return 1;
    }

    return 0;
}

static int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) {
    float ascii_count, c40_count, text_count, edi_count, byte_count;
    char reduced_char;
    int done, best_scheme, best_count, sp;

    /* Step J */
    if (current_mode == C1_ASCII) {
        ascii_count = 0.0;
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
            if (data_left >= 3) {
                if ((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) {
                    decimal_count = 3;
                }
            }

            if (decimal_count != 3) {
                int bits_left_in_byte, target_count;
                int sub_target;
                /* Finish Decimal mode and go back to ASCII */

                strcat(decimal_binary, "111111"); /* Unlatch */

                target_count = 3;
                if (strlen(decimal_binary) <= 16) {







|







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
            if (data_left >= 3) {
                if ((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) {
                    decimal_count = 3;
                }
            }

            if (decimal_count != 3) {
                size_t bits_left_in_byte, target_count;
                int sub_target;
                /* Finish Decimal mode and go back to ASCII */

                strcat(decimal_binary, "111111"); /* Unlatch */

                target_count = 3;
                if (strlen(decimal_binary) <= 16) {
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
                    strcat(decimal_binary, "01");
                }

                if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
                    if (decimal_count >= 1) {
                        int sub_value = ctoi(source[sp]) + 1;

                        if (sub_value & 0x08) {
                            strcat(decimal_binary, "1");
                        } else {
                            strcat(decimal_binary, "0");
                        }
                        if (sub_value & 0x04) {
                            strcat(decimal_binary, "1");
                        } else {
                            strcat(decimal_binary, "0");
                        }
                        if (sub_value & 0x02) {
                            strcat(decimal_binary, "1");
                        } else {
                            strcat(decimal_binary, "0");
                        }
                        if (sub_value & 0x01) {
                            strcat(decimal_binary, "1");
                        } else {
                            strcat(decimal_binary, "0");
                        }
                        sp++;
                    } else {
                        strcat(decimal_binary, "1111");
                    }
                }

                if (bits_left_in_byte == 6) {
                    strcat(decimal_binary, "01");
                }

                /* Binary buffer is full - transfer to target */
                if (target_count >= 1) {
                    sub_target = 0;
                    if (decimal_binary[0] == '1') {
                        sub_target += 128;
                    }
                    if (decimal_binary[1] == '1') {
                        sub_target += 64;
                    }
                    if (decimal_binary[2] == '1') {
                        sub_target += 32;
                    }
                    if (decimal_binary[3] == '1') {
                        sub_target += 16;
                    }
                    if (decimal_binary[4] == '1') {
                        sub_target += 8;
                    }
                    if (decimal_binary[5] == '1') {
                        sub_target += 4;
                    }
                    if (decimal_binary[6] == '1') {
                        sub_target += 2;
                    }
                    if (decimal_binary[7] == '1') {
                        sub_target += 1;
                    }
                    target[tp] = sub_target;
                    tp++;
                }
                if (target_count >= 2) {
                    sub_target = 0;
                    if (decimal_binary[8] == '1') {
                        sub_target += 128;
                    }
                    if (decimal_binary[9] == '1') {
                        sub_target += 64;
                    }
                    if (decimal_binary[10] == '1') {
                        sub_target += 32;
                    }
                    if (decimal_binary[11] == '1') {
                        sub_target += 16;
                    }
                    if (decimal_binary[12] == '1') {
                        sub_target += 8;
                    }
                    if (decimal_binary[13] == '1') {
                        sub_target += 4;
                    }
                    if (decimal_binary[14] == '1') {
                        sub_target += 2;
                    }
                    if (decimal_binary[15] == '1') {
                        sub_target += 1;
                    }
                    target[tp] = sub_target;
                    tp++;
                }
                if (target_count == 3) {
                    sub_target = 0;
                    if (decimal_binary[16] == '1') {
                        sub_target += 128;
                    }
                    if (decimal_binary[17] == '1') {
                        sub_target += 64;
                    }
                    if (decimal_binary[18] == '1') {
                        sub_target += 32;
                    }
                    if (decimal_binary[19] == '1') {
                        sub_target += 16;
                    }
                    if (decimal_binary[20] == '1') {
                        sub_target += 8;
                    }
                    if (decimal_binary[21] == '1') {
                        sub_target += 4;
                    }
                    if (decimal_binary[22] == '1') {
                        sub_target += 2;
                    }
                    if (decimal_binary[23] == '1') {
                        sub_target += 1;
                    }
                    target[tp] = sub_target;
                    tp++;
                }

                next_mode = C1_ASCII;
            } else {







|
<
<
<
<
|
|
|
|
|
<
<
<
<

<
<
<
<
|













<
<
|
<
|
<
|
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<





<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







883
884
885
886
887
888
889
890




891
892
893
894
895




896




897
898
899
900
901
902
903
904
905
906
907
908
909
910


911

912

913
914
915


916












917
918
919
920
921


922

923

924
925
926














927
928
929
930
931
932


933

934

935
936
937














938
939
940
941
942
943
944
                    strcat(decimal_binary, "01");
                }

                if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
                    if (decimal_count >= 1) {
                        int sub_value = ctoi(source[sp]) + 1;

                        for (i = 0x08; i > 0; i = i >> 1) {




                            if (sub_value & i) {
                                strcat(decimal_binary, "1");
                            } else {
                                strcat(decimal_binary, "0");
                            }




                        }




                        
                        sp++;
                    } else {
                        strcat(decimal_binary, "1111");
                    }
                }

                if (bits_left_in_byte == 6) {
                    strcat(decimal_binary, "01");
                }

                /* Binary buffer is full - transfer to target */
                if (target_count >= 1) {
                    sub_target = 0;


                    

                    for (i = 0; i < 8; i++) {

                        if (decimal_binary[i] == '1') {
                            sub_target += 128 >> i;
                        }


                    }












                    target[tp] = sub_target;
                    tp++;
                }
                if (target_count >= 2) {
                    sub_target = 0;


                    

                    for (i = 0; i < 8; i++) {

                        if (decimal_binary[i + 8] == '1') {
                            sub_target += 128 >> i;
                        }














                    }
                    target[tp] = sub_target;
                    tp++;
                }
                if (target_count == 3) {
                    sub_target = 0;


                    

                    for (i = 0; i < 8; i++) {

                        if (decimal_binary[i + 16] == '1') {
                            sub_target += 128 >> i;
                        }














                    }
                    target[tp] = sub_target;
                    tp++;
                }

                next_mode = C1_ASCII;
            } else {
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
                tp++;
                sp++;
            }
        }

        if (tp > 1480) {
            /* Data is too large for symbol */
            strcpy(symbol->errtxt, "Input data too long");
            return 0;
        }
    } while (sp < length);

    /* Empty buffers */
    if (c40_p == 2) {
        int iv;







|







1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
                tp++;
                sp++;
            }
        }

        if (tp > 1480) {
            /* Data is too large for symbol */
            strcpy(symbol->errtxt, "Input data too long (E10)");
            return 0;
        }
    } while (sp < length);

    /* Empty buffers */
    if (c40_p == 2) {
        int iv;
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
        target[tp] = iv % 256;
        tp++;
        target[tp] = 255;
        tp++; /* Unlatch */
    }

    if (current_mode == C1_DECIMAL) {
        int bits_left_in_byte, target_count;
        int sub_target;
        /* Finish Decimal mode and go back to ASCII */

        strcat(decimal_binary, "111111"); /* Unlatch */

        target_count = 3;
        if (strlen(decimal_binary) <= 16) {







|







1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
        target[tp] = iv % 256;
        tp++;
        target[tp] = 255;
        tp++; /* Unlatch */
    }

    if (current_mode == C1_DECIMAL) {
        size_t bits_left_in_byte, target_count;
        int sub_target;
        /* Finish Decimal mode and go back to ASCII */

        strcat(decimal_binary, "111111"); /* Unlatch */

        target_count = 3;
        if (strlen(decimal_binary) <= 16) {
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
        if (bits_left_in_byte == 6) {
            strcat(decimal_binary, "01");
        }

        /* Binary buffer is full - transfer to target */
        if (target_count >= 1) {
            sub_target = 0;
            if (decimal_binary[0] == '1') {
                sub_target += 128;
            }
            if (decimal_binary[1] == '1') {
                sub_target += 64;
            }
            if (decimal_binary[2] == '1') {
                sub_target += 32;
            }
            if (decimal_binary[3] == '1') {
                sub_target += 16;
            }
            if (decimal_binary[4] == '1') {
                sub_target += 8;
            }
            if (decimal_binary[5] == '1') {
                sub_target += 4;
            }
            if (decimal_binary[6] == '1') {
                sub_target += 2;
            }
            if (decimal_binary[7] == '1') {
                sub_target += 1;
            }
            target[tp] = sub_target;
            tp++;
        }
        if (target_count >= 2) {
            sub_target = 0;
            if (decimal_binary[8] == '1') {
                sub_target += 128;
            }
            if (decimal_binary[9] == '1') {
                sub_target += 64;
            }
            if (decimal_binary[10] == '1') {
                sub_target += 32;
            }
            if (decimal_binary[11] == '1') {
                sub_target += 16;
            }
            if (decimal_binary[12] == '1') {
                sub_target += 8;
            }
            if (decimal_binary[13] == '1') {
                sub_target += 4;
            }
            if (decimal_binary[14] == '1') {
                sub_target += 2;
            }
            if (decimal_binary[15] == '1') {
                sub_target += 1;
            }
            target[tp] = sub_target;
            tp++;
        }
        if (target_count == 3) {
            sub_target = 0;
            if (decimal_binary[16] == '1') {
                sub_target += 128;
            }
            if (decimal_binary[17] == '1') {
                sub_target += 64;
            }
            if (decimal_binary[18] == '1') {
                sub_target += 32;
            }
            if (decimal_binary[19] == '1') {
                sub_target += 16;
            }
            if (decimal_binary[20] == '1') {
                sub_target += 8;
            }
            if (decimal_binary[21] == '1') {
                sub_target += 4;
            }
            if (decimal_binary[22] == '1') {
                sub_target += 2;
            }
            if (decimal_binary[23] == '1') {
                sub_target += 1;
            }
            target[tp] = sub_target;
            tp++;
        }
    }

    if (current_mode == C1_BYTE) {







<
<
|
<
|
<
|
|
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<





<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1113
1114
1115
1116
1117
1118
1119


1120

1121

1122
1123
1124


1125












1126
1127
1128
1129
1130


1131

1132

1133
1134
1135














1136
1137
1138
1139
1140
1141


1142

1143

1144
1145
1146














1147
1148
1149
1150
1151
1152
1153
        if (bits_left_in_byte == 6) {
            strcat(decimal_binary, "01");
        }

        /* Binary buffer is full - transfer to target */
        if (target_count >= 1) {
            sub_target = 0;


            

            for (i = 0; i < 8; i++) {

                if (decimal_binary[i] == '1') {
                    sub_target += 128 >> i;
                }


            }












            target[tp] = sub_target;
            tp++;
        }
        if (target_count >= 2) {
            sub_target = 0;


            

            for (i = 0; i < 8; i++) {

                if (decimal_binary[i + 8] == '1') {
                    sub_target += 128 >> i;
                }














            }
            target[tp] = sub_target;
            tp++;
        }
        if (target_count == 3) {
            sub_target = 0;


            

            for (i = 0; i < 8; i++) {

                if (decimal_binary[i + 16] == '1') {
                    sub_target += 128 >> i;
                }














            }
            target[tp] = sub_target;
            tp++;
        }
    }

    if (current_mode == C1_BYTE) {
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
            tp += 2;
        }
    }

    /* Re-check length of data */
    if (tp > 1480) {
        /* Data is too large for symbol */
        strcpy(symbol->errtxt, "Input data too long");
        return 0;
    }
    /* 
    printf("targets:\n");
    for(i = 0; i < tp; i++) {
            printf("[%d]", target[i]);
    }







|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
            tp += 2;
        }
    }

    /* Re-check length of data */
    if (tp > 1480) {
        /* Data is too large for symbol */
        strcpy(symbol->errtxt, "Input data too long (E11)");
        return 0;
    }
    /* 
    printf("targets:\n");
    for(i = 0; i < tp; i++) {
            printf("[%d]", target[i]);
    }
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
    int size = 1, i, j, data_blocks;

    char datagrid[136][120];
    int row, col;
    int sub_version = 0;

    if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
        strcpy(symbol->errtxt, "Invalid symbol size");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (symbol->option_2 == 9) {
        /* Version S */
        int codewords;
        short int elreg[112];
        unsigned int data[15], ecc[15];
        int stream[30];
        int block_width;

        if (length > 18) {
            strcpy(symbol->errtxt, "Input data too long");
            return ZINT_ERROR_TOO_LONG;
        }
        if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid input data (Version S encodes numeric input only)");
            return ZINT_ERROR_INVALID_DATA;
        }

        sub_version = 3;
        codewords = 12;
        block_width = 6; /* Version S-30 */
        if (length <= 12) {







|












|



|







1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
    int size = 1, i, j, data_blocks;

    char datagrid[136][120];
    int row, col;
    int sub_version = 0;

    if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
        strcpy(symbol->errtxt, "Invalid symbol size (E12)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (symbol->option_2 == 9) {
        /* Version S */
        int codewords;
        short int elreg[112];
        unsigned int data[15], ecc[15];
        int stream[30];
        int block_width;

        if (length > 18) {
            strcpy(symbol->errtxt, "Input data too long (E13)");
            return ZINT_ERROR_TOO_LONG;
        }
        if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid input data (Version S encodes numeric input only) (E14)");
            return ZINT_ERROR_INVALID_DATA;
        }

        sub_version = 3;
        codewords = 12;
        block_width = 6; /* Version S-30 */
        if (length <= 12) {
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
        data_length = c1_encode(symbol, source, data, length);

        if (data_length == 0) {
            return ZINT_ERROR_TOO_LONG;
        }

        if (data_length > 38) {
            strcpy(symbol->errtxt, "Input data too long");
            return ZINT_ERROR_TOO_LONG;
        }

        size = 10;
        sub_version = 3;
        data_cw = 38;
        ecc_cw = 22;







|







1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
        data_length = c1_encode(symbol, source, data, length);

        if (data_length == 0) {
            return ZINT_ERROR_TOO_LONG;
        }

        if (data_length > 38) {
            strcpy(symbol->errtxt, "Input data too long (E15)");
            return ZINT_ERROR_TOO_LONG;
        }

        size = 10;
        sub_version = 3;
        data_cw = 38;
        ecc_cw = 22;
Changes to jni/zint/backend/code128.c.
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
    j = 0;
    bar_characters = 0;
    f_state = 0;

    if (sourcelen > 160) {
        /* This only blocks rediculously long input - the actual length of the
           resulting barcode depends on the type of data, so this is trapped later */
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Detect extended ASCII characters */
    for (i = 0; i < sourcelen; i++) {
        if (source[i] >= 128)
            fset[i] = 'f';







|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
    j = 0;
    bar_characters = 0;
    f_state = 0;

    if (sourcelen > 160) {
        /* This only blocks rediculously long input - the actual length of the
           resulting barcode depends on the type of data, so this is trapped later */
        strcpy(symbol->errtxt, "Input too long (C40)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Detect extended ASCII characters */
    for (i = 0; i < sourcelen; i++) {
        if (source[i] >= 128)
            fset[i] = 'f';
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

        if (set[i] == 'C') {
            glyph_count = glyph_count + 0.5;
        } else {
            glyph_count = glyph_count + 1.0;
        }
    }
    if (glyph_count > 80.0) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* So now we know what start character to use - we can get on with it! */
    if (symbol->output_options & READER_INIT) {
        /* Reader Initialisation mode */
        switch (set[0]) {







|
|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

        if (set[i] == 'C') {
            glyph_count = glyph_count + 0.5;
        } else {
            glyph_count = glyph_count + 1.0;
        }
    }
    if (glyph_count > 60.0) {
        strcpy(symbol->errtxt, "Input too long (C41)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* So now we know what start character to use - we can get on with it! */
    if (symbol->output_options & READER_INIT) {
        /* Reader Initialisation mode */
        switch (set[0]) {
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    /* Stop character */
    strcat(dest, C128Table[106]);
    expand(symbol, dest);
    return error_number;
}

/* Handle EAN-128 (Now known as GS1-128) */
int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, j, values[170], bar_characters, read, total_sum;
    int error_number, indexchaine, indexliste;
    char set[170], mode, last_set;
    float glyph_count;
    char dest[1000];
    int separator_row, linkage_flag, c_count;
#ifndef _MSC_VER







|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    /* Stop character */
    strcat(dest, C128Table[106]);
    expand(symbol, dest);
    return error_number;
}

/* Handle EAN-128 (Now known as GS1-128) */
int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
    int i, j, values[170], bar_characters, read, total_sum;
    int error_number, indexchaine, indexliste;
    char set[170], mode, last_set;
    float glyph_count;
    char dest[1000];
    int separator_row, linkage_flag, c_count;
#ifndef _MSC_VER
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

    memset(values, 0, sizeof (values));
    memset(set, ' ', sizeof (set));

    if (length > 160) {
        /* This only blocks rediculously long input - the actual length of the
        resulting barcode depends on the type of data, so this is trapped later */
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    for (i = 0; i < length; i++) {
        if (source[i] == '\0') {
            /* Null characters not allowed! */
            strcpy(symbol->errtxt, "NULL character in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* if part of a composite symbol make room for the separator pattern */
    if (symbol->symbology == BARCODE_EAN128_CC) {
        separator_row = symbol->rows;







|





|







703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

    memset(values, 0, sizeof (values));
    memset(set, ' ', sizeof (set));

    if (length > 160) {
        /* This only blocks rediculously long input - the actual length of the
        resulting barcode depends on the type of data, so this is trapped later */
        strcpy(symbol->errtxt, "Input too long (C42)");
        return ZINT_ERROR_TOO_LONG;
    }
    for (i = 0; i < length; i++) {
        if (source[i] == '\0') {
            /* Null characters not allowed! */
            strcpy(symbol->errtxt, "NULL character in input data (C43)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* if part of a composite symbol make room for the separator pattern */
    if (symbol->symbology == BARCODE_EAN128_CC) {
        separator_row = symbol->rows;
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

        if ((set[i] == 'C') && (reduced[i] != '[')) {
            glyph_count = glyph_count + 0.5;
        } else {
            glyph_count = glyph_count + 1.0;
        }
    }
    if (glyph_count > 80.0) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* So now we know what start character to use - we can get on with it! */
    switch (set[0]) {
        case 'A': /* Start A */
            strcat(dest, C128Table[103]);







|
|







838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

        if ((set[i] == 'C') && (reduced[i] != '[')) {
            glyph_count = glyph_count + 0.5;
        } else {
            glyph_count = glyph_count + 1.0;
        }
    }
    if (glyph_count > 60.0) {
        strcpy(symbol->errtxt, "Input too long (C44)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* So now we know what start character to use - we can get on with it! */
    switch (set[0]) {
        case 'A': /* Start A */
            strcat(dest, C128Table[103]);
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
    int error_number, zeroes, i, nve_check, total_sum, sourcelen;
    unsigned char ean128_equiv[25];

    memset(ean128_equiv, 0, 25);
    sourcelen = length;

    if (sourcelen > 17) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    zeroes = 17 - sourcelen;
    strcpy((char *) ean128_equiv, "[00]");
    memset(ean128_equiv + 4, '0', zeroes);
    strcpy((char*) ean128_equiv + 4 + zeroes, (char*) source);








|





|







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
    int error_number, zeroes, i, nve_check, total_sum, sourcelen;
    unsigned char ean128_equiv[25];

    memset(ean128_equiv, 0, 25);
    sourcelen = length;

    if (sourcelen > 17) {
        strcpy(symbol->errtxt, "Input too long (C45)");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C46)");
        return error_number;
    }
    zeroes = 17 - sourcelen;
    strcpy((char *) ean128_equiv, "[00]");
    memset(ean128_equiv + 4, '0', zeroes);
    strcpy((char*) ean128_equiv + 4 + zeroes, (char*) source);

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
/* EAN-14 - A version of EAN-128 */
int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, count, check_digit;
    int error_number, zeroes;
    unsigned char ean128_equiv[20];

    if (length > 13) {
        strcpy(symbol->errtxt, "Input wrong length");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data");
        return error_number;
    }

    zeroes = 13 - length;
    strcpy((char*) ean128_equiv, "[01]");
    memset(ean128_equiv + 4, '0', zeroes);
    ustrcpy(ean128_equiv + 4 + zeroes, source);







|





|







1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
/* EAN-14 - A version of EAN-128 */
int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, count, check_digit;
    int error_number, zeroes;
    unsigned char ean128_equiv[20];

    if (length > 13) {
        strcpy(symbol->errtxt, "Input wrong length (C47)");
        return ZINT_ERROR_TOO_LONG;
    }

    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid character in data (C48)");
        return error_number;
    }

    zeroes = 13 - length;
    strcpy((char*) ean128_equiv, "[01]");
    memset(ean128_equiv + 4, '0', zeroes);
    ustrcpy(ean128_equiv + 4 + zeroes, source);
Changes to jni/zint/backend/code16k.c.
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
    } else {
        gs1 = 0;
    }

    if (input_length > 157) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    bar_characters = 0;

    /* Detect extended ASCII characters */
    for (i = 0; i < (unsigned int) input_length; i++) {







|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
    } else {
        gs1 = 0;
    }

    if (input_length > 157) {
        strcpy(symbol->errtxt, "Input too long (D20)");
        return ZINT_ERROR_TOO_LONG;
    }

    bar_characters = 0;

    /* Detect extended ASCII characters */
    for (i = 0; i < (unsigned int) input_length; i++) {
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

    if ((gs1) && (set[0] != 'A')) {
        /* FNC1 can be integrated with mode character */
        glyph_count--;
    }

    if (glyph_count > 77.0) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Calculate how tall the symbol will be */
    glyph_count = glyph_count + 2.0;
    i = glyph_count;
    rows_needed = (i / 5);







|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

    if ((gs1) && (set[0] != 'A')) {
        /* FNC1 can be integrated with mode character */
        glyph_count--;
    }

    if (glyph_count > 77.0) {
        strcpy(symbol->errtxt, "Input too long (D21)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Calculate how tall the symbol will be */
    glyph_count = glyph_count + 2.0;
    i = glyph_count;
    rows_needed = (i / 5);
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    }

    if (symbol->output_options & READER_INIT) {
        if (m == 2) {
            m = 5;
        }
        if (gs1) {
            strcpy(symbol->errtxt, "Cannot use both GS1 mode and Reader Initialisation");
            return ZINT_ERROR_INVALID_OPTION;
        } else {
            if ((set[0] == 'B') && (set[1] == 'C')) {
                m = 6;
            }
        }
        values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */







|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    }

    if (symbol->output_options & READER_INIT) {
        if (m == 2) {
            m = 5;
        }
        if (gs1) {
            strcpy(symbol->errtxt, "Cannot use both GS1 mode and Reader Initialisation (D22)");
            return ZINT_ERROR_INVALID_OPTION;
        } else {
            if ((set[0] == 'B') && (set[1] == 'C')) {
                m = 6;
            }
        }
        values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */
Changes to jni/zint/backend/code49.c.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    int w_grid[8][4]; /* Refets to table 2 */
    int pad_count = 0;
    char pattern[40];
    int gs1;
    size_t h;

    if (length > 81) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
        strcpy(intermediate, "*"); /* FNC1 */
    } else {
        gs1 = 0;
    }

    for (i = 0; i < length; i++) {
        if (source[i] > 127) {
            strcpy(symbol->errtxt, "Invalid characters in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
        if (gs1 && (source[i] == '['))
            strcat(intermediate, "*"); /* FNC1 */
        else
            strcat(intermediate, c49_table7[source[i]]);
    }







|











|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    int w_grid[8][4]; /* Refets to table 2 */
    int pad_count = 0;
    char pattern[40];
    int gs1;
    size_t h;

    if (length > 81) {
        strcpy(symbol->errtxt, "Input too long (D30)");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->input_mode == GS1_MODE) {
        gs1 = 1;
        strcpy(intermediate, "*"); /* FNC1 */
    } else {
        gs1 = 0;
    }

    for (i = 0; i < length; i++) {
        if (source[i] > 127) {
            strcpy(symbol->errtxt, "Invalid characters in input data (D31)");
            return ZINT_ERROR_INVALID_DATA;
        }
        if (gs1 && (source[i] == '['))
            strcat(intermediate, "*"); /* FNC1 */
        else
            strcat(intermediate, c49_table7[source[i]]);
    }
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
        case 44: M = 5;
            break;
        default: M = 0;
            break;
    }

    if (M != 0) {

        for (i = 0; i < codeword_count; i++) {
            codewords[i] = codewords[i + 1];
        }
        codeword_count--;
    }

    if (codeword_count > 49) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Place codewords in code character array (c grid) */
    rows = 0;
    do {
        for (i = 0; i < 7; i++) {







>



<



|







204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
        case 44: M = 5;
            break;
        default: M = 0;
            break;
    }

    if (M != 0) {
        codeword_count--;
        for (i = 0; i < codeword_count; i++) {
            codewords[i] = codewords[i + 1];
        }

    }

    if (codeword_count > 49) {
        strcpy(symbol->errtxt, "Input too long (D32)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Place codewords in code character array (c grid) */
    rows = 0;
    do {
        for (i = 0; i < 7; i++) {
325
326
327
328
329
330
331

332

333
334
335
336

        /* Expand into symbol */
        symbol->row_height[i] = 10;
        expand(symbol, pattern);
    }

    symbol->whitespace_width = 10;

    symbol->output_options = BARCODE_BIND;

    symbol->border_width = 2;

    return 0;
}







>
|
>




325
326
327
328
329
330
331
332
333
334
335
336
337
338

        /* Expand into symbol */
        symbol->row_height[i] = 10;
        expand(symbol, pattern);
    }

    symbol->whitespace_width = 10;
    if (!(symbol->output_options & BARCODE_BIND)) {
        symbol->output_options += BARCODE_BIND;
    }
    symbol->border_width = 2;

    return 0;
}
Changes to jni/zint/backend/common.c.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

/* Local replacement for strlen() with unsigned char strings */
int ustrlen(const unsigned char data[]) {
    return strlen((const char*) data);
}

/* Local replacement for strcpy() with unsigned char strings */

void ustrcpy(unsigned char target[], const unsigned char source[]) {
    strcpy((char *) target, (const char*) source);
}

/* Converts a character 0-9 to its equivalent integer value */
int ctoi(const char source) {
    if ((source >= '0') && (source <= '9'))
        return (source - '0');
    return (source - 'A' + 10);
}

/* Converts an integer value to its hexadecimal character */
char itoc(const int source) {
    if ((source >= 0) && (source <= 9)) {
        return ('0' + source);
    } else {
        return ('A' + (source - 10));
    }
}

/* Converts lower case characters to upper case in a string source[] */
void to_upper(unsigned char source[]) {
    unsigned int i, src_len = ustrlen(source);

    for (i = 0; i < src_len; i++) {
        if ((source[i] >= 'a') && (source[i] <= 'z')) {
            source [i] = (source[i] - 'a') + 'A';
        }
    }
}

/* Verifies that a string only uses valid characters */
int is_sane(char test_string[], const unsigned char source[], const int length) {
    unsigned int i, j, latch;
    unsigned int lt = strlen(test_string);

    for (i = 0; i < length; i++) {
        latch = FALSE;
        for (j = 0; j < lt; j++) {
            if (source[i] == test_string[j]) {
                latch = TRUE;
                break;
            }
        }
        if (!(latch)) {
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    return 0;
}

/* Returns the position of data in set_string */
int posn(char set_string[], const char data) {
    unsigned int i, n = strlen(set_string);

    for (i = 0; i < n; i++) {
        if (data == set_string[i]) {
            return i;
        }
    }
    return 0;
}

/* Replaces huge switch statements for looking up in tables */
void lookup(char set_string[], const char *table[], const char data, char dest[]) {
    unsigned int i, n = strlen(set_string);

    for (i = 0; i < n; i++) {
        if (data == set_string[i]) {
            strcat(dest, table[i]);
        }
    }
}

/* Return true (1) if a module is dark/black, orherwise false (0) */
int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    return (symbol->encoded_data[y_coord][x_coord / 7] >> (x_coord % 7)) & 1;
}

/* Set a module to dark/black */
void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    symbol->encoded_data[y_coord][x_coord / 7] |= 1 << (x_coord % 7);
}

/* Set (or unset) a module to white */
void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    symbol->encoded_data[y_coord][x_coord / 7] &= ~(1 << (x_coord % 7));
}

/* Expands from a width pattern to a bit pattern */
void expand(struct zint_symbol *symbol, char data[]) {

    unsigned int reader, n = strlen(data);
    int writer, i;
    char latch;

    writer = 0;
    latch = '1';

    for (reader = 0; reader < n; reader++) {







|



<
<
<
<
<
<


















|









|
|
|


















|
|










|
|








|















|

|







31
32
33
34
35
36
37
38
39
40
41






42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

/* Local replacement for strlen() with unsigned char strings */
size_t ustrlen(const unsigned char data[]) {
    return strlen((const char*) data);
}







/* Converts a character 0-9 to its equivalent integer value */
int ctoi(const char source) {
    if ((source >= '0') && (source <= '9'))
        return (source - '0');
    return (source - 'A' + 10);
}

/* Converts an integer value to its hexadecimal character */
char itoc(const int source) {
    if ((source >= 0) && (source <= 9)) {
        return ('0' + source);
    } else {
        return ('A' + (source - 10));
    }
}

/* Converts lower case characters to upper case in a string source[] */
void to_upper(unsigned char source[]) {
    size_t i, src_len = ustrlen(source);

    for (i = 0; i < src_len; i++) {
        if ((source[i] >= 'a') && (source[i] <= 'z')) {
            source [i] = (source[i] - 'a') + 'A';
        }
    }
}

/* Verifies that a string only uses valid characters */
int is_sane(const char test_string[], const unsigned char source[], const size_t length) {
    unsigned int j, latch;
    size_t i, lt = strlen(test_string);

    for (i = 0; i < length; i++) {
        latch = FALSE;
        for (j = 0; j < lt; j++) {
            if (source[i] == test_string[j]) {
                latch = TRUE;
                break;
            }
        }
        if (!(latch)) {
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    return 0;
}

/* Returns the position of data in set_string */
int posn(const char set_string[], const char data) {
    size_t i, n = strlen(set_string);

    for (i = 0; i < n; i++) {
        if (data == set_string[i]) {
            return i;
        }
    }
    return 0;
}

/* Replaces huge switch statements for looking up in tables */
void lookup(const char set_string[], const char *table[], const char data, char dest[]) {
    size_t i, n = strlen(set_string);

    for (i = 0; i < n; i++) {
        if (data == set_string[i]) {
            strcat(dest, table[i]);
        }
    }
}

/* Return true (1) if a module is dark/black, otherwise false (0) */
int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    return (symbol->encoded_data[y_coord][x_coord / 7] >> (x_coord % 7)) & 1;
}

/* Set a module to dark/black */
void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    symbol->encoded_data[y_coord][x_coord / 7] |= 1 << (x_coord % 7);
}

/* Set (or unset) a module to white */
void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
    symbol->encoded_data[y_coord][x_coord / 7] &= ~(1 << (x_coord % 7));
}

/* Expands from a width pattern to a bit pattern */
void expand(struct zint_symbol *symbol, const char data[]) {

    size_t reader, n = strlen(data);
    int writer, i;
    char latch;

    writer = 0;
    latch = '1';

    for (reader = 0; reader < n; reader++) {
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
        }
    }
    symbol->rows = symbol->rows + 1;
}

/* Indicates which symbologies can have row binding */
int is_stackable(const int symbology) {
    if (symbology < BARCODE_PDF417) {
        return 1;
    }
    if (symbology == BARCODE_CODE128B) {
        return 1;
    }
    if (symbology == BARCODE_ISBNX) {
        return 1;
    }



    if (symbology == BARCODE_EAN14) {
        return 1;
    }
    if (symbology == BARCODE_NVE18) {
        return 1;
    }
    if (symbology == BARCODE_KOREAPOST) {
        return 1;
    }
    if (symbology == BARCODE_PLESSEY) {
        return 1;
    }
    if (symbology == BARCODE_TELEPEN_NUM) {
        return 1;
    }
    if (symbology == BARCODE_ITF14) {
        return 1;
    }
    if (symbology == BARCODE_CODE32) {

        return 1;
    }

    return 0;
}

/* Indicates which symbols can have addon (EAN-2 and EAN-5) */
int is_extendable(const int symbology) {
    if (symbology == BARCODE_EANX) {
        return 1;
    }







<
|
|
|
|

<
<
|
>
>
>
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
>
|


|







157
158
159
160
161
162
163

164
165
166
167
168


169
170
171
172
173


174


175


176


177


178


179
180
181
182
183
184
185
186
187
188
189
190
191
        }
    }
    symbol->rows = symbol->rows + 1;
}

/* Indicates which symbologies can have row binding */
int is_stackable(const int symbology) {

    int retval = 0;

    if (symbology < BARCODE_PDF417) {
        retval = 1;
    }



    switch (symbology) {
        case BARCODE_CODE128B:
        case BARCODE_ISBNX:
        case BARCODE_EAN14:


        case BARCODE_NVE18:


        case BARCODE_KOREAPOST:


        case BARCODE_PLESSEY:


        case BARCODE_TELEPEN_NUM:


        case BARCODE_ITF14:


        case BARCODE_CODE32:
        case BARCODE_CODABLOCKF:
            retval = 1;
    }

    return retval;
}

/* Indicates which symbols can have addon (EAN-2 and EAN-5) */
int is_extendable(const int symbology) {
    if (symbology == BARCODE_EANX) {
        return 1;
    }
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
























            return 1;
        }
    }

    return 0;
}

/* Convert Unicode to Latin-1 for those symbologies which only support Latin-1 */
int latin1_process(struct zint_symbol *symbol, const unsigned char source[], unsigned char preprocessed[], int *length) {
    int j, i, next;

    j = 0;
    i = 0;
    do {
        next = -1;
        if (source[i] < 128) {
            preprocessed[j] = source[i];
            j++;
            next = i + 1;
        } else {
            if (source[i] == 0xC2) {
                preprocessed[j] = source[i + 1];
                j++;
                next = i + 2;
            }
            if (source[i] == 0xC3) {
                preprocessed[j] = source[i + 1] + 64;
                j++;
                next = i + 2;
            }
        }
        if (next == -1) {
            strcpy(symbol->errtxt, "error: Invalid character in input string (only Latin-1 characters supported)");
            return ZINT_ERROR_INVALID_DATA;
        }
        i = next;
    } while (i < *length);
    preprocessed[j] = '\0';
    *length = j;

    return 0;
}

int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length) {
    int bpos, jpos, error_number;
    int next;

    bpos = 0;
    jpos = 0;
    error_number = 0;
    next = 0;

    do {
        if (source[bpos] <= 0x7f) {
            /* 1 byte mode (7-bit ASCII) */
            vals[jpos] = source[bpos];
            next = bpos + 1;
            jpos++;
        } else {
            if ((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) {
                strcpy(symbol->errtxt, "Corrupt Unicode data");
                return ZINT_ERROR_INVALID_DATA;
            }
            if ((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) {
                strcpy(symbol->errtxt, "Overlong encoding not supported");
                return ZINT_ERROR_INVALID_DATA;
            }

            if ((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) {
                /* 2 byte mode */
                vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f);
                next = bpos + 2;
                jpos++;
            } else
                if ((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) {
                /* 3 byte mode */
                vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f);
                next = bpos + 3;
                jpos++;
            } else
                if (source[bpos] >= 0xf0) {
                strcpy(symbol->errtxt, "Unicode sequences of more than 3 bytes not supported");
                return ZINT_ERROR_INVALID_DATA;
            }
        }

        bpos = next;

    } while (bpos < *length);
    *length = jpos;

    return error_number;
}
































<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















|



|
















|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
217
218
219
220
221
222
223




































224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
            return 1;
        }
    }

    return 0;
}





































int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length) {
    int bpos, jpos, error_number;
    int next;

    bpos = 0;
    jpos = 0;
    error_number = 0;
    next = 0;

    do {
        if (source[bpos] <= 0x7f) {
            /* 1 byte mode (7-bit ASCII) */
            vals[jpos] = source[bpos];
            next = bpos + 1;
            jpos++;
        } else {
            if ((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) {
                strcpy(symbol->errtxt, "Corrupt Unicode data (B40)");
                return ZINT_ERROR_INVALID_DATA;
            }
            if ((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) {
                strcpy(symbol->errtxt, "Overlong encoding not supported (B41)");
                return ZINT_ERROR_INVALID_DATA;
            }

            if ((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) {
                /* 2 byte mode */
                vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f);
                next = bpos + 2;
                jpos++;
            } else
                if ((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) {
                /* 3 byte mode */
                vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f);
                next = bpos + 3;
                jpos++;
            } else
                if (source[bpos] >= 0xf0) {
                strcpy(symbol->errtxt, "Unicode sequences of more than 3 bytes not supported (B42)");
                return ZINT_ERROR_INVALID_DATA;
            }
        }

        bpos = next;

    } while (bpos < *length);
    *length = jpos;

    return error_number;
}

void set_minimum_height(struct zint_symbol *symbol, int min_height) {
    /* Enforce minimum permissable height of rows */
    int fixed_height = 0;
    int zero_count = 0;
    int i;
    
    for (i = 0; i < symbol->rows; i++) {
        fixed_height += symbol->row_height[i];
        
        if (symbol->row_height[i] == 0) {
            zero_count++;
        }
    }
    
    if (zero_count > 0) {
        if (((symbol->height - fixed_height) / zero_count) < min_height) {
            for (i = 0; i < symbol->rows; i++) {
                if (symbol->row_height[i] == 0) {
                    symbol->row_height[i] = min_height;
                }
            }
        }
    }
}
Changes to jni/zint/backend/common.h.
42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
#define TRUE		1
#endif

/* The most commonly used set */
#define NEON	"0123456789"

#include "zint.h"




#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern int ustrlen(const unsigned char source[]);
    extern void ustrcpy(unsigned char target[], const unsigned char source[]);
    extern int ctoi(const char source);
    extern char itoc(const int source);
    extern void to_upper(unsigned char source[]);
    extern int is_sane(char test_string[], const unsigned char source[], const int length);
    extern void lookup(char set_string[], const char *table[], const char data, char dest[]);
    extern int posn(char set_string[], const char data);
    extern void expand(struct zint_symbol *symbol, char data[]);
    extern int is_stackable(const int symbology);
    extern int is_extendable(const int symbology);
    extern int roundup(const float input);
    extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern int istwodigits(const unsigned char source[], const int position);
    extern double froundup(const double input);
    extern int parunmodd(const unsigned char llyth);
    extern int latin1_process(struct zint_symbol *symbol, const unsigned char source[], unsigned char preprocessed[], int *length);
    extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __COMMON_H */







>
>
>





|
<



|
|
|
|









<

>





42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
#define TRUE		1
#endif

/* The most commonly used set */
#define NEON	"0123456789"

#include "zint.h"
#include <stdlib.h>

#define ustrcpy(target,source) strcpy((char*)target,(const char*)source)

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern size_t ustrlen(const unsigned char source[]);

    extern int ctoi(const char source);
    extern char itoc(const int source);
    extern void to_upper(unsigned char source[]);
    extern int is_sane(const char test_string[], const unsigned char source[], const size_t length);
    extern void lookup(const char set_string[], const char *table[], const char data, char dest[]);
    extern int posn(const char set_string[], const char data);
    extern void expand(struct zint_symbol *symbol, const char data[]);
    extern int is_stackable(const int symbology);
    extern int is_extendable(const int symbology);
    extern int roundup(const float input);
    extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
    extern int istwodigits(const unsigned char source[], const int position);
    extern double froundup(const double input);
    extern int parunmodd(const unsigned char llyth);

    extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length);
    extern void set_minimum_height(struct zint_symbol *symbol, int min_height);
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __COMMON_H */
Changes to jni/zint/backend/composite.c.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "pdf417.h"
#include "gs1.h"

#define UINT unsigned short

extern int general_rules(char field[], char type[]);
extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length);
extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length);

static UINT pwr928[69][7];

int _min(int first, int second) {







|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "pdf417.h"
#include "gs1.h"

#define UINT unsigned short

extern int general_rules(char field[], char type[]);
extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length);
extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length);
extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length);

static UINT pwr928[69][7];

int _min(int first, int second) {
789
790
791
792
793
794
795








































































































































































































































796
797
798
799
800
801
802
        symbol->row_height[i] = 3;
    }
    symbol->rows = (mclength / cc_width);
    symbol->width = strlen(pattern);

    return 0;
}









































































































































































































































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 */
    int encoding_method, read_posn, d1, d2, value, alpha_pad;
    int i, j, mask, ai_crop, fnc1_latch;
    long int group_val;
    int ai90_mode, latch, remainder, binary_length;
    char date_str[4];







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
        symbol->row_height[i] = 3;
    }
    symbol->rows = (mclength / cc_width);
    symbol->width = strlen(pattern);

    return 0;
}

int calc_padding_cca(int binary_length, int cc_width) {
    int target_bitsize = 0;
    
    switch (cc_width) {
        case 2:
            if (binary_length <= 167) {
                target_bitsize = 167;
            }
            if (binary_length <= 138) {
                target_bitsize = 138;
            }
            if (binary_length <= 118) {
                target_bitsize = 118;
            }
            if (binary_length <= 108) {
                target_bitsize = 108;
            }
            if (binary_length <= 88) {
                target_bitsize = 88;
            }
            if (binary_length <= 78) {
                target_bitsize = 78;
            }
            if (binary_length <= 59) {
                target_bitsize = 59;
            }
            break;
        case 3:
            if (binary_length <= 167) {
                target_bitsize = 167;
            }
            if (binary_length <= 138) {
                target_bitsize = 138;
            }
            if (binary_length <= 118) {
                target_bitsize = 118;
            }
            if (binary_length <= 98) {
                target_bitsize = 98;
            }
            if (binary_length <= 78) {
                target_bitsize = 78;
            }
            break;
        case 4:
            if (binary_length <= 197) {
                target_bitsize = 197;
            }
            if (binary_length <= 167) {
                target_bitsize = 167;
            }
            if (binary_length <= 138) {
                target_bitsize = 138;
            }
            if (binary_length <= 108) {
                target_bitsize = 108;
            }
            if (binary_length <= 78) {
                target_bitsize = 78;
            }
            break;
        }
    
        return target_bitsize;
}

int calc_padding_ccb(int binary_length, int cc_width) {
    int target_bitsize = 0;
    
    switch (cc_width) {
        case 2:
            if (binary_length <= 336) {
                target_bitsize = 336;
            }
            if (binary_length <= 296) {
                target_bitsize = 296;
            }
            if (binary_length <= 256) {
                target_bitsize = 256;
            }
            if (binary_length <= 208) {
                target_bitsize = 208;
            }
            if (binary_length <= 160) {
                target_bitsize = 160;
            }
            if (binary_length <= 104) {
                target_bitsize = 104;
            }
            if (binary_length <= 56) {
                target_bitsize = 56;
            }
            break;
        case 3:
            if (binary_length <= 768) {
                target_bitsize = 768;
            }
            if (binary_length <= 648) {
                target_bitsize = 648;
            }
            if (binary_length <= 536) {
                target_bitsize = 536;
            }
            if (binary_length <= 416) {
                target_bitsize = 416;
            }
            if (binary_length <= 304) {
                target_bitsize = 304;
            }
            if (binary_length <= 208) {
                target_bitsize = 208;
            }
            if (binary_length <= 152) {
                target_bitsize = 152;
            }
            if (binary_length <= 112) {
                target_bitsize = 112;
            }
            if (binary_length <= 72) {
                target_bitsize = 72;
            }
            if (binary_length <= 32) {
                target_bitsize = 32;
            }
            break;
        case 4:
            if (binary_length <= 1184) {
                target_bitsize = 1184;
            }
            if (binary_length <= 1016) {
                target_bitsize = 1016;
            }
            if (binary_length <= 840) {
                target_bitsize = 840;
            }
            if (binary_length <= 672) {
                target_bitsize = 672;
            }
            if (binary_length <= 496) {
                target_bitsize = 496;
            }
            if (binary_length <= 352) {
                target_bitsize = 352;
            }
            if (binary_length <= 264) {
                target_bitsize = 264;
            }
            if (binary_length <= 208) {
                target_bitsize = 208;
            }
            if (binary_length <= 152) {
                target_bitsize = 152;
            }
            if (binary_length <= 96) {
                target_bitsize = 96;
            }
            if (binary_length <= 56) {
                target_bitsize = 56;
            }
            break;
    }
    
    return target_bitsize;
}

int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int *ecc) {
    int target_bitsize = 0;
    int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
    int codewords_total, target_codewords, target_bytesize;
    int i;

    byte_length = binary_length / 8;
    if (binary_length % 8 != 0) {
        byte_length++;
    }

    codewords_used = (byte_length / 6) * 5;
    codewords_used += byte_length % 6;

    ecc_level = 7;
    if (codewords_used <= 1280) {
        ecc_level = 6;
    }
    if (codewords_used <= 640) {
        ecc_level = 5;
    }
    if (codewords_used <= 320) {
        ecc_level = 4;
    }
    if (codewords_used <= 160) {
        ecc_level = 3;
    }
    if (codewords_used <= 40) {
        ecc_level = 2;
    }
    *(ecc) = ecc_level;
    ecc_codewords = 1;
    for (i = 1; i <= (ecc_level + 1); i++) {
        ecc_codewords *= 2;
    }

    codewords_used += ecc_codewords;
    codewords_used += 3;

    *(cc_width) = (lin_width - 62) / 17;
    /* stop the symbol from becoming too high */
    do {
        *(cc_width) = *(cc_width) + 1;
        rows = codewords_used / *(cc_width);
    } while (rows > 90);

    if (codewords_used % *(cc_width) != 0) {
        rows++;
    }

    codewords_total = *(cc_width) * rows;
    
    if (codewords_total > 928) { // PDF_MAX
        return 0;
    }

    target_codewords = codewords_total - ecc_codewords;
    target_codewords -= 3;

    target_bytesize = 6 * (target_codewords / 5);
    target_bytesize += target_codewords % 5;

    target_bitsize = 8 * target_bytesize;
    
    return target_bitsize;
}

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 */
    int encoding_method, read_posn, d1, d2, value, alpha_pad;
    int i, j, mask, ai_crop, fnc1_latch;
    long int group_val;
    int ai90_mode, latch, remainder, binary_length;
    char date_str[4];
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
                case '/': alphanum += 1;
                    break;
            }

            if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) {
                if ((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) {
                    /* An Invalid AI 90 character */
                    strcpy(symbol->errtxt, "Invalid AI 90 data");
                    return ZINT_ERROR_INVALID_DATA;
                }
            }
        }

        /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */
        test1 = -1;







|







1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
                case '/': alphanum += 1;
                    break;
            }

            if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) {
                if ((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) {
                    /* An Invalid AI 90 character */
                    strcpy(symbol->errtxt, "Invalid AI 90 data (D40)");
                    return ZINT_ERROR_INVALID_DATA;
                }
            }
        }

        /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */
        test1 = -1;
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

    }

    general_field_type[strlen(general_field)] = '\0';

    if (latch == 1) {
        /* Invalid characters in input data */
        strcpy(symbol->errtxt, "Invalid characters in input data");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < (int) strlen(general_field); i++) {
        if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) {
            general_field_type[i + 1] = ISOIEC;
        }







|







1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539

    }

    general_field_type[strlen(general_field)] = '\0';

    if (latch == 1) {
        /* Invalid characters in input data */
        strcpy(symbol->errtxt, "Invalid characters in input data (D41)");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < (int) strlen(general_field); i++) {
        if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) {
            general_field_type[i + 1] = ISOIEC;
        }
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
                if (general_field[i] == '_') strcat(binary_string, "11111011"); /* underline or low line */
                if (general_field[i] == ' ') strcat(binary_string, "11111100"); /* space */

                i++;
                break;
        }
    } while (i + latch < (int) strlen(general_field));

    binary_length = strlen(binary_string);
    if (cc_mode == 1) {
        /* CC-A 2D component - calculate remaining space */
        switch (*(cc_width)) {
            case 2:
                if (binary_length > 167) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 118) {
                    target_bitsize = 118;
                }
                if (binary_length <= 108) {
                    target_bitsize = 108;
                }
                if (binary_length <= 88) {
                    target_bitsize = 88;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                if (binary_length <= 59) {
                    target_bitsize = 59;
                }
                break;
            case 3:
                if (binary_length > 167) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 118) {
                    target_bitsize = 118;
                }
                if (binary_length <= 98) {
                    target_bitsize = 98;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                break;
            case 4:
                if (binary_length > 197) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 197) {
                    target_bitsize = 197;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 108) {
                    target_bitsize = 108;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                break;
        }
    }

    if (cc_mode == 2) {
        /* CC-B 2D component - calculated from ISO/IEC 24728 Table 1  */
        switch (*(cc_width)) {
            case 2:
                if (binary_length > 336) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 336) {
                    target_bitsize = 336;
                }
                if (binary_length <= 296) {
                    target_bitsize = 296;
                }
                if (binary_length <= 256) {
                    target_bitsize = 256;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 160) {
                    target_bitsize = 160;
                }
                if (binary_length <= 104) {
                    target_bitsize = 104;
                }
                if (binary_length <= 56) {
                    target_bitsize = 56;
                }
                break;
            case 3:
                if (binary_length > 768) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 768) {
                    target_bitsize = 768;
                }
                if (binary_length <= 648) {
                    target_bitsize = 648;
                }
                if (binary_length <= 536) {
                    target_bitsize = 536;
                }
                if (binary_length <= 416) {
                    target_bitsize = 416;
                }
                if (binary_length <= 304) {
                    target_bitsize = 304;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 152) {
                    target_bitsize = 152;
                }
                if (binary_length <= 112) {
                    target_bitsize = 112;
                }
                if (binary_length <= 72) {
                    target_bitsize = 72;
                }
                if (binary_length <= 32) {
                    target_bitsize = 32;
                }
                break;
            case 4:
                if (binary_length > 1184) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 1184) {
                    target_bitsize = 1184;
                }
                if (binary_length <= 1016) {
                    target_bitsize = 1016;
                }
                if (binary_length <= 840) {
                    target_bitsize = 840;
                }
                if (binary_length <= 672) {
                    target_bitsize = 672;
                }
                if (binary_length <= 496) {
                    target_bitsize = 496;
                }
                if (binary_length <= 352) {
                    target_bitsize = 352;
                }
                if (binary_length <= 264) {
                    target_bitsize = 264;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 152) {
                    target_bitsize = 152;
                }
                if (binary_length <= 96) {
                    target_bitsize = 96;
                }
                if (binary_length <= 56) {
                    target_bitsize = 56;
                }
                break;
        }
    }

    if (cc_mode == 3) {
        /* CC-C 2D Component is a bit more complex! */
        int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
        int codewords_total, target_codewords, target_bytesize;

        byte_length = binary_length / 8;
        if (binary_length % 8 != 0) {
            byte_length++;
        }

        codewords_used = (byte_length / 6) * 5;
        codewords_used += byte_length % 6;

        ecc_level = 7;
        if (codewords_used <= 1280) {
            ecc_level = 6;
        }
        if (codewords_used <= 640) {
            ecc_level = 5;
        }
        if (codewords_used <= 320) {
            ecc_level = 4;
        }
        if (codewords_used <= 160) {
            ecc_level = 3;
        }
        if (codewords_used <= 40) {
            ecc_level = 2;
        }
        *(ecc) = ecc_level;
        ecc_codewords = 1;
        for (i = 1; i <= (ecc_level + 1); i++) {
            ecc_codewords *= 2;
        }

        codewords_used += ecc_codewords;
        codewords_used += 3;

        if (codewords_used > symbol->option_3) {
            return ZINT_ERROR_TOO_LONG;
        }

        *(cc_width) = (lin_width - 62) / 17;
        if ((codewords_used / *(cc_width)) > 90) {
            /* stop the symbol from becoming too high */
            *(cc_width) = *(cc_width) + 1;
        }

        rows = codewords_used / *(cc_width);
        if (codewords_used % *(cc_width) != 0) {
            rows++;
        }

        codewords_total = *(cc_width) * rows;

        target_codewords = codewords_total - ecc_codewords;
        target_codewords -= 3;

        target_bytesize = 6 * (target_codewords / 5);
        target_bytesize += target_codewords % 5;

        target_bitsize = 8 * target_bytesize;
    }

    remainder = binary_length - target_bitsize;

    if (latch == 1) {
        i = 0;
        /* There is still one more numeric digit to encode */

        if ((remainder >= 4) && (remainder <= 6)) {
            d1 = ctoi(general_field[i]);







|

|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<







1716
1717
1718
1719
1720
1721
1722
1723
1724
1725


1726




1727



















1728
1729






























1730







1731






1732






















1733

1734



1735


1736













1737






















































1738







































1739
1740
1741



















1742



1743
1744
1745
1746
1747
1748
1749
                if (general_field[i] == '_') strcat(binary_string, "11111011"); /* underline or low line */
                if (general_field[i] == ' ') strcat(binary_string, "11111100"); /* space */

                i++;
                break;
        }
    } while (i + latch < (int) strlen(general_field));
    
    binary_length = strlen(binary_string);
    switch (cc_mode) {


        case 1:




            target_bitsize = calc_padding_cca(binary_length, *(cc_width));



















            break;
        case 2:






























            target_bitsize = calc_padding_ccb(binary_length, *(cc_width));







            break;






        case 3:






















            target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);

            break;



    }


    













    if (target_bitsize == 0) {






















































        strcpy(symbol->errtxt, "Input too long for selected 2d component (D42)");







































        return ZINT_ERROR_TOO_LONG;
    }




















    remainder = target_bitsize - binary_length;




    if (latch == 1) {
        i = 0;
        /* There is still one more numeric digit to encode */

        if ((remainder >= 4) && (remainder <= 6)) {
            d1 = ctoi(general_field[i]);
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
                mask = mask >> 1;
            }
            /* This may push the symbol up to the next size */
        }
    }

    if (strlen(binary_string) > 11805) { /* (2361 * 5) */
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* all the code below is repeated from above - it needs to be calculated again because the
       size of the symbol may have changed when adding data in the above sequence */

    binary_length = strlen(binary_string);
    if (cc_mode == 1) {
        /* CC-A 2D component - calculate padding required */
        switch (*(cc_width)) {
            case 2:
                if (binary_length > 167) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 118) {
                    target_bitsize = 118;
                }
                if (binary_length <= 108) {
                    target_bitsize = 108;
                }
                if (binary_length <= 88) {
                    target_bitsize = 88;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                if (binary_length <= 59) {
                    target_bitsize = 59;
                }
                break;
            case 3:
                if (binary_length > 167) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 118) {
                    target_bitsize = 118;
                }
                if (binary_length <= 98) {
                    target_bitsize = 98;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                break;
            case 4:
                if (binary_length > 197) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 197) {
                    target_bitsize = 197;
                }
                if (binary_length <= 167) {
                    target_bitsize = 167;
                }
                if (binary_length <= 138) {
                    target_bitsize = 138;
                }
                if (binary_length <= 108) {
                    target_bitsize = 108;
                }
                if (binary_length <= 78) {
                    target_bitsize = 78;
                }
                break;
        }
    }

    if (cc_mode == 2) {
        /* CC-B 2D component */
        switch (*(cc_width)) {
            case 2:
                if (binary_length > 336) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 336) {
                    target_bitsize = 336;
                }
                if (binary_length <= 296) {
                    target_bitsize = 296;
                }
                if (binary_length <= 256) {
                    target_bitsize = 256;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 160) {
                    target_bitsize = 160;
                }
                if (binary_length <= 104) {
                    target_bitsize = 104;
                }
                if (binary_length <= 56) {
                    target_bitsize = 56;
                }
                break;
            case 3:
                if (binary_length > 768) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 768) {
                    target_bitsize = 768;
                }
                if (binary_length <= 648) {
                    target_bitsize = 648;
                }
                if (binary_length <= 536) {
                    target_bitsize = 536;
                }
                if (binary_length <= 416) {
                    target_bitsize = 416;
                }
                if (binary_length <= 304) {
                    target_bitsize = 304;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 152) {
                    target_bitsize = 152;
                }
                if (binary_length <= 112) {
                    target_bitsize = 112;
                }
                if (binary_length <= 72) {
                    target_bitsize = 72;
                }
                if (binary_length <= 32) {
                    target_bitsize = 32;
                }
                break;
            case 4:
                if (binary_length > 1184) {
                    return ZINT_ERROR_TOO_LONG;
                }
                if (binary_length <= 1184) {
                    target_bitsize = 1184;
                }
                if (binary_length <= 1016) {
                    target_bitsize = 1016;
                }
                if (binary_length <= 840) {
                    target_bitsize = 840;
                }
                if (binary_length <= 672) {
                    target_bitsize = 672;
                }
                if (binary_length <= 496) {
                    target_bitsize = 496;
                }
                if (binary_length <= 352) {
                    target_bitsize = 352;
                }
                if (binary_length <= 264) {
                    target_bitsize = 264;
                }
                if (binary_length <= 208) {
                    target_bitsize = 208;
                }
                if (binary_length <= 152) {
                    target_bitsize = 152;
                }
                if (binary_length <= 96) {
                    target_bitsize = 96;
                }
                if (binary_length <= 56) {
                    target_bitsize = 56;
                }
                break;
        }
    }

    if (cc_mode == 3) {
        /* CC-C 2D Component is a bit more complex! */
        int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
        int codewords_total, target_codewords, target_bytesize;

        byte_length = binary_length / 8;
        if (binary_length % 8 != 0) {
            byte_length++;
        }

        codewords_used = (byte_length / 6) * 5;
        codewords_used += byte_length % 6;

        ecc_level = 7;
        if (codewords_used <= 1280) {
            ecc_level = 6;
        }
        if (codewords_used <= 640) {
            ecc_level = 5;
        }
        if (codewords_used <= 320) {
            ecc_level = 4;
        }
        if (codewords_used <= 160) {
            ecc_level = 3;
        }
        if (codewords_used <= 40) {
            ecc_level = 2;
        }
        *(ecc) = ecc_level;
        ecc_codewords = 1;
        for (i = 1; i <= (ecc_level + 1); i++) {
            ecc_codewords *= 2;
        }

        codewords_used += ecc_codewords;
        codewords_used += 3;

        if (codewords_used > symbol->option_3) {
            return ZINT_ERROR_TOO_LONG;
        }

        *(cc_width) = (lin_width - 62) / 17;
        if ((codewords_used / *(cc_width)) > 90) {
            /* stop the symbol from becoming too high */
            *(cc_width) = *(cc_width) + 1;
        }

        rows = codewords_used / *(cc_width);
        if (codewords_used % *(cc_width) != 0) {
            rows++;
        }

        codewords_total = *(cc_width) * rows;

        target_codewords = codewords_total - ecc_codewords;
        target_codewords -= 3;

        target_bytesize = 6 * (target_codewords / 5);
        target_bytesize += target_codewords % 5;

        target_bitsize = 8 * target_bytesize;
    }

    if (binary_length < target_bitsize) {
        /* Now add padding to binary string */
        if (alpha_pad == 1) {
            strcat(binary_string, "11111");
            alpha_pad = 0;







|



<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784


1785






















































1786


















1787


1788




1789



















1790
1791













1792



















1793
1794































1795




1796
1797






1798




1799


1800


























1801






















1802
1803
1804
1805
1806
1807
1808
                mask = mask >> 1;
            }
            /* This may push the symbol up to the next size */
        }
    }

    if (strlen(binary_string) > 11805) { /* (2361 * 5) */
        strcpy(symbol->errtxt, "Input too long (D43)");
        return ZINT_ERROR_TOO_LONG;
    }


























































    binary_length = strlen(binary_string);


















    switch (cc_mode) {


        case 1:




            target_bitsize = calc_padding_cca(binary_length, *(cc_width));



















            break;
        case 2:













            target_bitsize = calc_padding_ccb(binary_length, *(cc_width));



















            break;
        case 3:































            target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);




            break;
    }






    




    if (target_bitsize == 0) {


        strcpy(symbol->errtxt, "Input too long for selected 2d component (D44)");


























        return ZINT_ERROR_TOO_LONG;






















    }

    if (binary_length < target_bitsize) {
        /* Now add padding to binary string */
        if (alpha_pad == 1) {
            strcat(binary_string, "11111");
            alpha_pad = 0;
2087
2088
2089
2090
2091
2092
2093



















2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109

2110

2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123





2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
    if (zsecond_len) {
        memmove(symbol->primary + n + zsecond_len, symbol->primary + n, second_len);
        memset(symbol->primary + n, '0', zsecond_len);
        n += zsecond_len + second_len;
    }
    symbol->primary[n] = '\0';
}




















int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
    int error_number, cc_mode, cc_width, ecc_level;
    int j, i, k;
    unsigned int rs = length + 1;
    unsigned int bs = 20 * rs;
    unsigned int pri_len;
#ifndef _MSC_VER
    char reduced[rs];
    char binary_string[bs];
#else
    char* reduced = (char*) _alloca(rs);
    char* binary_string = (char*) _alloca(bs);
#endif
    struct zint_symbol *linear;
    int top_shift, bottom_shift;



    error_number = 0;
    pri_len = strlen(symbol->primary);
    if (pri_len == 0) {
        strcpy(symbol->errtxt, "No primary (linear) message in 2D composite");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (length > 2990) {
        strcpy(symbol->errtxt, "2D component input data too long");
        return ZINT_ERROR_TOO_LONG;
    }

    linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */






    error_number = gs1_verify(symbol, source, length, reduced);
    if (error_number != 0) {
        return error_number;
    }

    cc_mode = symbol->option_1;

    if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) {
        /* CC-C can only be used with a GS1-128 linear part */
        strcpy(symbol->errtxt, "Invalid mode (CC-C only valid with GS1-128 linear component)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    linear->symbology = symbol->symbology;

    if (linear->symbology != BARCODE_EAN128_CC) {
        /* Set the "component linkage" flag in the linear component */
        linear->option_1 = 2;
    } else {
        /* GS1-128 needs to know which type of 2D component is used */
        linear->option_1 = cc_mode;
    }

    switch (symbol->symbology) {
        case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
            break;
    }

    if (error_number != 0) {
        strcpy(symbol->errtxt, linear->errtxt);
        strcat(symbol->errtxt, " in linear component");
        return error_number;
    }

    switch (symbol->symbology) {
            /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
        case BARCODE_EANX_CC:
            switch (pri_len) {
                case 7: /* EAN-8 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
|
>



|




|


|
|
>
>
>
>
>





|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944






































1945
1946
1947
1948
1949
1950
1951
    if (zsecond_len) {
        memmove(symbol->primary + n + zsecond_len, symbol->primary + n, second_len);
        memset(symbol->primary + n, '0', zsecond_len);
        n += zsecond_len + second_len;
    }
    symbol->primary[n] = '\0';
}

int linear_dummy_run(unsigned char *source, int length) {
    struct zint_symbol *dummy;
    int error_number;
    int linear_width;
    
    dummy = ZBarcode_Create();
    dummy->symbology = BARCODE_EAN128_CC;
    dummy->option_1 = 3;
    error_number = ean_128(dummy, source, length);
    linear_width = dummy->width;
    ZBarcode_Delete(dummy);
    
    if (error_number == 0) {
        return linear_width;
    } else {
        return 0;
    }
}

int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
    int error_number, cc_mode, cc_width, ecc_level;
    int j, i, k;
    unsigned int rs = length + 1;
    unsigned int bs = 20 * rs;
    unsigned int pri_len;
#ifndef _MSC_VER
    char reduced[rs];
    char binary_string[bs];
#else
    char* reduced = (char*) _alloca(rs);
    char* binary_string = (char*) _alloca(bs);
#endif
    struct zint_symbol *linear;
    int top_shift, bottom_shift;
    int linear_width = 0;
    
    /* Perform sanity checks on input options first */
    error_number = 0;
    pri_len = strlen(symbol->primary);
    if (pri_len == 0) {
        strcpy(symbol->errtxt, "No primary (linear) message in 2D composite (D45)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (length > 2990) {
        strcpy(symbol->errtxt, "2D component input data too long (D46)");
        return ZINT_ERROR_TOO_LONG;
    }
    
    cc_mode = symbol->option_1;
    if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) {
        /* CC-C can only be used with a GS1-128 linear part */
        strcpy(symbol->errtxt, "Invalid mode (CC-C only valid with GS1-128 linear component) (D47)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    error_number = gs1_verify(symbol, source, length, reduced);
    if (error_number != 0) {
        return error_number;
    }
    
    if (symbol->symbology == BARCODE_EAN128_CC) {
        /* Do a test run of encoding the linear component to establish its width */
        linear_width = linear_dummy_run((unsigned char *) symbol->primary, pri_len);
        if (linear_width == 0) {
            strcpy(symbol->errtxt, "Invalid data (D48)");
            return ZINT_ERROR_INVALID_DATA;
        }






































    }

    switch (symbol->symbology) {
            /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
        case BARCODE_EANX_CC:
            switch (pri_len) {
                case 7: /* EAN-8 */
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258











































2259
2260
2261
2262
2263
2264
2265
        case BARCODE_RSS14STACK_CC: cc_width = 2;
            break;
        case BARCODE_RSS14_OMNI_CC: cc_width = 2;
            break;
        case BARCODE_RSS_EXPSTACK_CC: cc_width = 4;
            break;
    }

    memset(binary_string, 0, bs);

    if (cc_mode < 1 || cc_mode > 3) {
        cc_mode = 1;
    }

    if (cc_mode == 1) {
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width);
        if (i == ZINT_ERROR_TOO_LONG) {
            cc_mode = 2;
        }
    }

    if (cc_mode == 2) {
        /* If the data didn't fit into CC-A it is recalculated for CC-B */
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width);
        if (i == ZINT_ERROR_TOO_LONG) {
            if (symbol->symbology != BARCODE_EAN128_CC) {
                return ZINT_ERROR_TOO_LONG;
            } else {
                cc_mode = 3;
            }
        }
    }

    if (cc_mode == 3) {
        /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width);
        if (i == ZINT_ERROR_TOO_LONG) {
            return ZINT_ERROR_TOO_LONG;
        }
    }

    switch (cc_mode) {
            /* Note that ecc_level is only relevant to CC-C */
        case 1: error_number = cc_a(symbol, binary_string, cc_width);
            break;
        case 2: error_number = cc_b(symbol, binary_string, cc_width);
            break;
        case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level);
            break;
    }

    if (error_number != 0) {
        return ZINT_ERROR_ENCODING_PROBLEM;
    }












































    /* Merge the linear component with the 2D component */

    top_shift = 0;
    bottom_shift = 0;

    switch (symbol->symbology) {







|







|







|











|


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
        case BARCODE_RSS14STACK_CC: cc_width = 2;
            break;
        case BARCODE_RSS14_OMNI_CC: cc_width = 2;
            break;
        case BARCODE_RSS_EXPSTACK_CC: cc_width = 4;
            break;
    }
    
    memset(binary_string, 0, bs);

    if (cc_mode < 1 || cc_mode > 3) {
        cc_mode = 1;
    }

    if (cc_mode == 1) {
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
        if (i == ZINT_ERROR_TOO_LONG) {
            cc_mode = 2;
        }
    }

    if (cc_mode == 2) {
        /* If the data didn't fit into CC-A it is recalculated for CC-B */
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
        if (i == ZINT_ERROR_TOO_LONG) {
            if (symbol->symbology != BARCODE_EAN128_CC) {
                return ZINT_ERROR_TOO_LONG;
            } else {
                cc_mode = 3;
            }
        }
    }

    if (cc_mode == 3) {
        /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */
        i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
        if (i == ZINT_ERROR_TOO_LONG) {
            return ZINT_ERROR_TOO_LONG;
        }
    }

    switch (cc_mode) {
            /* Note that ecc_level is only relevant to CC-C */
        case 1: error_number = cc_a(symbol, binary_string, cc_width);
            break;
        case 2: error_number = cc_b(symbol, binary_string, cc_width);
            break;
        case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level);
            break;
    }

    if (error_number != 0) {
        return ZINT_ERROR_ENCODING_PROBLEM;
    }
    
    /* 2D component done, now calculate linear component */
    linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */
    
    linear->symbology = symbol->symbology;

    if (linear->symbology != BARCODE_EAN128_CC) {
        /* Set the "component linkage" flag in the linear component */
        linear->option_1 = 2;
    } else {
        /* GS1-128 needs to know which type of 2D component is used */
        linear->option_1 = cc_mode;
    }

    switch (symbol->symbology) {
        case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
            break;
        case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
            break;
    }

    if (error_number != 0) {
        strcpy(symbol->errtxt, linear->errtxt);
        strcat(symbol->errtxt, " in linear component ");
        ZBarcode_Delete(linear);
        return error_number;
    }

    /* Merge the linear component with the 2D component */

    top_shift = 0;
    bottom_shift = 0;

    switch (symbol->symbology) {
Changes to jni/zint/backend/dmatrix.c.
42
43
44
45
46
47
48




49
50
51
52
53
54
55
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#ifdef _MSC_VER
#include <malloc.h>




#endif
#include "reedsol.h"
#include "common.h"
#include "dmatrix.h"

/* Annex M placement alorithm low level */
static void ecc200placementbit(int *array, const int NR, const int NC, int r, int c, const int p, const char b) {







>
>
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#ifdef _MSC_VER
#include <malloc.h>
/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */
#if _MSC_VER < 1800
#define ceilf ceil
#endif
#endif
#include "reedsol.h"
#include "common.h"
#include "dmatrix.h"

/* Annex M placement alorithm low level */
static void ecc200placementbit(int *array, const int NR, const int NC, int r, int c, const int p, const char b) {
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    int i;
    int nonX12Position = 0;
    int specialX12Position = 0;
    int retval = 0;

    for (i = position; i < sourcelen; i++) {
        if (nonX12Position == 0) {
            if (isX12(i) == 1) {
                nonX12Position = i;
            }
        }

        if (specialX12Position == 0) {
            if ((inputData[i] == (char) 13) ||
                    (inputData[i] == '*') ||







|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    int i;
    int nonX12Position = 0;
    int specialX12Position = 0;
    int retval = 0;

    for (i = position; i < sourcelen; i++) {
        if (nonX12Position == 0) {
            if (isX12(inputData[i]) != 1) {
                nonX12Position = i;
            }
        }

        if (specialX12Position == 0) {
            if ((inputData[i] == (char) 13) ||
                    (inputData[i] == '*') ||
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count;
    int sp, best_scheme;

    best_scheme = DM_NULL;

    /* step (j) */
    if (current_mode == DM_ASCII) {
        ascii_count = 0.0;
        c40_count = 1.0;
        text_count = 1.0;
        x12_count = 1.0;
        edf_count = 1.0;
        b256_count = 1.25;
    } else {
        ascii_count = 1.0;
        c40_count = 2.0;
        text_count = 2.0;
        x12_count = 2.0;
        edf_count = 2.0;
        b256_count = 2.25;
    }

    switch (current_mode) {
        case DM_C40: c40_count = 0.0;
            break;
        case DM_TEXT: text_count = 0.0;
            break;
        case DM_X12: x12_count = 0.0;
            break;
        case DM_EDIFACT: edf_count = 0.0;
            break;
        case DM_BASE256: b256_count = 0.0;
            break;
    }

    sp = position;

    do {
        if (sp == (sourcelen - 1)) {
            /* At the end of data ... step (k) */
            ascii_count = ceil(ascii_count);
            b256_count = ceil(b256_count);
            edf_count = ceil(edf_count);
            text_count = ceil(text_count);
            x12_count = ceil(x12_count);
            c40_count = ceil(c40_count);

            best_count = c40_count;
            best_scheme = DM_C40; // (k)(7)

            if (x12_count < best_count) {
                best_count = x12_count;
                best_scheme = DM_X12; // (k)(6)







|
|
|
|
|
|

|
|
|
|
|
|



|

|

|

|

|








|
|
|
|
|
|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count;
    int sp, best_scheme;

    best_scheme = DM_NULL;

    /* step (j) */
    if (current_mode == DM_ASCII) {
        ascii_count = 0.0F;
        c40_count = 1.0F;
        text_count = 1.0F;
        x12_count = 1.0F;
        edf_count = 1.0F;
        b256_count = 1.25F;
    } else {
        ascii_count = 1.0F;
        c40_count = 2.0F;
        text_count = 2.0F;
        x12_count = 2.0F;
        edf_count = 2.0F;
        b256_count = 2.25F;
    }

    switch (current_mode) {
        case DM_C40: c40_count = 0.0F;
            break;
        case DM_TEXT: text_count = 0.0F;
            break;
        case DM_X12: x12_count = 0.0F;
            break;
        case DM_EDIFACT: edf_count = 0.0F;
            break;
        case DM_BASE256: b256_count = 0.0F;
            break;
    }

    sp = position;

    do {
        if (sp == (sourcelen - 1)) {
            /* At the end of data ... step (k) */
            ascii_count = ceilf(ascii_count);
            b256_count = ceilf(b256_count);
            edf_count = ceilf(edf_count);
            text_count = ceilf(text_count);
            x12_count = ceilf(x12_count);
            c40_count = ceilf(c40_count);

            best_count = c40_count;
            best_scheme = DM_C40; // (k)(7)

            if (x12_count < best_count) {
                best_count = x12_count;
                best_scheme = DM_X12; // (k)(6)
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
        } else {

            /* ascii ... step (l) */
            if ((inputData[sp] >= '0') && (inputData[sp] <= '9')) {
                ascii_count += 0.5F; // (l)(1)
            } else {
                if (inputData[sp] > 127) {
                    ascii_count = ceil(ascii_count) + 2.0F; // (l)(2)
                } else {
                    ascii_count = ceil(ascii_count) + 1.0F; // (l)(3)
                }
            }

            /* c40 ... step (m) */
            if ((inputData[sp] == ' ') ||
                    (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
                    ((inputData[sp] >= 'A') && (inputData[sp] <= 'Z')))) {







|

|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
        } else {

            /* ascii ... step (l) */
            if ((inputData[sp] >= '0') && (inputData[sp] <= '9')) {
                ascii_count += 0.5F; // (l)(1)
            } else {
                if (inputData[sp] > 127) {
                    ascii_count = ceilf(ascii_count) + 2.0F; // (l)(2)
                } else {
                    ascii_count = ceilf(ascii_count) + 1.0F; // (l)(3)
                }
            }

            /* c40 ... step (m) */
            if ((inputData[sp] == ' ') ||
                    (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
                    ((inputData[sp] >= 'A') && (inputData[sp] <= 'Z')))) {
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570








571
572
573
574
575
576
577
        tp++;
        strcat(binary, " ");
        if (debug) printf("FN1 ");
    } /* FNC1 */

    if (symbol->output_options & READER_INIT) {
        if (gs1) {
            strcpy(symbol->errtxt, "Cannot encode in GS1 mode and Reader Initialisation at the same time");
            return ZINT_ERROR_INVALID_OPTION;
        } else {
            target[tp] = 234;
            tp++; /* Reader Programming */
            strcat(binary, " ");
            if (debug) printf("RP ");
        }
    }









    /* Check for Macro05/Macro06 */
    /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
    /* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
    if (tp == 0 && sp == 0 && inputlen >= 9
            && source[0] == '[' && source[1] == ')' && source[2] == '>'
            && source[3] == '\x1e' && source[4] == '0'







|








>
>
>
>
>
>
>
>







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
        tp++;
        strcat(binary, " ");
        if (debug) printf("FN1 ");
    } /* FNC1 */

    if (symbol->output_options & READER_INIT) {
        if (gs1) {
            strcpy(symbol->errtxt, "Cannot encode in GS1 mode and Reader Initialisation at the same time (E10)");
            return ZINT_ERROR_INVALID_OPTION;
        } else {
            target[tp] = 234;
            tp++; /* Reader Programming */
            strcat(binary, " ");
            if (debug) printf("RP ");
        }
    }

    if (symbol->eci > 3) {
        target[tp] = 241; /* ECI Character */
        tp++;
        target[tp] = (unsigned char) (symbol->eci + 1);
        tp++;
        if (debug) printf("ECI %d ", symbol->eci + 1);
    }

    /* Check for Macro05/Macro06 */
    /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
    /* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
    if (tp == 0 && sp == 0 && inputlen >= 9
            && source[0] == '[' && source[1] == ')' && source[2] == '>'
            && source[3] == '\x1e' && source[4] == '0'
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = iv / 256;
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];







|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = (unsigned char) (iv / 256);
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = iv / 256;
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];







|







781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = (unsigned char) (iv / 256);
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = iv / 256;
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];







|







842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
                process_buffer[*process_p] = value;
                (*process_p)++;

                if (*process_p >= 3) {
                    int iv;

                    iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
                    target[tp] = (unsigned char) (iv / 256);
                    tp++;
                    target[tp] = iv % 256;
                    tp++;
                    strcat(binary, "  ");
                    if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);

                    process_buffer[0] = process_buffer[3];
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895

                process_buffer[*process_p] = value;
                (*process_p)++;
                sp++;
            }

            if (*process_p >= 4) {
                target[tp] = (process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4);
                tp++;
                target[tp] = ((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2);
                tp++;
                target[tp] = ((process_buffer[2] & 0x03) << 6) + process_buffer[3];
                tp++;
                strcat(binary, "   ");
                if (debug) printf("[%d %d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2], process_buffer[3]);

                process_buffer[0] = process_buffer[4];
                process_buffer[1] = process_buffer[5];
                process_buffer[2] = process_buffer[6];







|



|







889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907

                process_buffer[*process_p] = value;
                (*process_p)++;
                sp++;
            }

            if (*process_p >= 4) {
                target[tp] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
                tp++;
                target[tp] = ((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2);
                tp++;
                target[tp] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + process_buffer[3]);
                tp++;
                strcat(binary, "   ");
                if (debug) printf("[%d %d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2], process_buffer[3]);

                process_buffer[0] = process_buffer[4];
                process_buffer[1] = process_buffer[5];
                process_buffer[2] = process_buffer[6];
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
    for (i = 0; i < tp; i++) {
        if (binary[i] == 'b') {
            int prn, temp;

            prn = ((149 * (i + 1)) % 255) + 1;
            temp = target[i] + prn;
            if (temp <= 255) {
                target[i] = temp;
            } else {
                target[i] = temp - 256;
            }
        }
    }

    *(last_mode) = current_mode;
    return tp;
}







|

|







966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
    for (i = 0; i < tp; i++) {
        if (binary[i] == 'b') {
            int prn, temp;

            prn = ((149 * (i + 1)) % 255) + 1;
            temp = target[i] + prn;
            if (temp <= 255) {
                target[i] = (unsigned char) (temp);
            } else {
                target[i] = (unsigned char) (temp - 256);
            }
        }
    }

    *(last_mode) = current_mode;
    return tp;
}
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062


1063
1064







1065










1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }
            }
            break;

        case DM_EDIFACT:
            if (symbols_left == process_p) // Unlatch not required!
            {
                if (process_p == 1) {
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }

                if (process_p == 2) {
                    target[target_length] = source[inputlen - 2] + 1;
                    target_length++;
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }



                if (process_p == 3) // Append edifact unlatch value (31) and encode as triple.







                {










                    target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
                    target_length++;
                    target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2));
                    target_length++;
                    target[target_length] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + 31);
                    target_length++;
                }
            }

            if (symbols_left > process_p) // Unlatch and encode remaining data in ascii.
            {
                // Edifact unlatch.
                if (symbols_left < 3) {
                    target[target_length] = 31;
                    target_length++;
                } else
                    target[target_length] = (31 << 2);
                target_length++;

                if (process_p == 1) {
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }

                if (process_p == 2) {
                    target[target_length] = source[inputlen - 2] + 1;
                    target_length++;
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }

                if (process_p == 3) {
                    target[target_length] = source[inputlen - 3] + 1;
                    target_length++;
                    target[target_length] = source[inputlen - 2] + 1;
                    target_length++;
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }
            }
            break;
    }

    if (debug) {
        int i;
        printf("\n\n");







|












>
>

|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104































1105
1106
1107
1108
1109
1110
1111
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }
            }
            break;

        case DM_EDIFACT:
            if (symbols_left <= 2) // Unlatch not required!
            {
                if (process_p == 1) {
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }

                if (process_p == 2) {
                    target[target_length] = source[inputlen - 2] + 1;
                    target_length++;
                    target[target_length] = source[inputlen - 1] + 1;
                    target_length++;
                }
            } else {
                // Append edifact unlatch value (31) and encode as triple.

                if (process_p == 1) {
                    target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((31 & 0x30) >> 4));
                    target_length++;
                    target[target_length] = (unsigned char) ((31 & 0x0f) << 4);
                    target_length++;
                    target[target_length] = (unsigned char) 0;
                    target_length++;
                }

                if (process_p == 2) {
                    target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
                    target_length++;
                    target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((31 & 0x3c) >> 2));
                    target_length++;
                    target[target_length] = (unsigned char) (((31 & 0x03) << 6));
                    target_length++;
                }

                if (process_p == 3) {
                    target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
                    target_length++;
                    target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2));
                    target_length++;
                    target[target_length] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + 31);
                    target_length++;
                }
































            }
            break;
    }

    if (debug) {
        int i;
        printf("\n\n");
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
        if (i == tail_length) {
            target[tp] = 129;
            tp++; /* Pad */
        } else {
            prn = ((149 * (tp + 1)) % 253) + 1;
            temp = 129 + prn;
            if (temp <= 254) {
                target[tp] = temp;
                tp++;
            } else {
                target[tp] = temp - 254;
                tp++;
            }
        }
    }
}

int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], const int length) {
    int inputlen, i, skew = 0;
    unsigned char binary[2200];
    int binlen;
    int process_buffer[8]; /* holds remaining data to finalised */
    int process_p; /* number of characters left to finalise */
    int symbolsize, optionsize, calcsize;
    int taillength, error_number = 0;
    int H, W, FH, FW, datablock, bytes, rsblock;
    int last_mode;
    unsigned char *grid = 0;
    int symbols_left;
    inputlen = length;

    /* inputlen may be decremented by 2 if macro character is used */
    binlen = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p);

    if (binlen == 0) {
        strcpy(symbol->errtxt, "Data too long to fit in symbol");
        return ZINT_ERROR_TOO_LONG;
    }

    if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {
        optionsize = intsymbol[symbol->option_2 - 1];
    } else {
        optionsize = -1;







|


|






|
|







|


<





|







1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
        if (i == tail_length) {
            target[tp] = 129;
            tp++; /* Pad */
        } else {
            prn = ((149 * (tp + 1)) % 253) + 1;
            temp = 129 + prn;
            if (temp <= 254) {
                target[tp] = (unsigned char) (temp);
                tp++;
            } else {
                target[tp] = (unsigned char) (temp - 254);
                tp++;
            }
        }
    }
}

int data_matrix_200(struct zint_symbol *symbol, const unsigned char source[], const int in_length) {
    int i, inputlen = in_length, skew = 0;
    unsigned char binary[2200];
    int binlen;
    int process_buffer[8]; /* holds remaining data to finalised */
    int process_p; /* number of characters left to finalise */
    int symbolsize, optionsize, calcsize;
    int taillength, error_number = 0;
    int H, W, FH, FW, datablock, bytes, rsblock;
    int last_mode = DM_ASCII;
    unsigned char *grid = 0;
    int symbols_left;


    /* inputlen may be decremented by 2 if macro character is used */
    binlen = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p);

    if (binlen == 0) {
        strcpy(symbol->errtxt, "Data too long to fit in symbol (E11)");
        return ZINT_ERROR_TOO_LONG;
    }

    if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {
        optionsize = intsymbol[symbol->option_2 - 1];
    } else {
        optionsize = -1;
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204

    symbolsize = optionsize;
    if (calcsize > optionsize) {
        symbolsize = calcsize;
        if (optionsize != -1) {
            /* flag an error */
            error_number = ZINT_WARN_INVALID_OPTION;
            strcpy(symbol->errtxt, "Data does not fit in selected symbol size");
        }
    }

    // Now we know the symbol size we can handle the remaining data in the process buffer.
    symbols_left = matrixbytes[symbolsize] - binlen;
    binlen = dm200encode_remainder(binary, binlen, source, inputlen, last_mode, process_buffer, process_p, symbols_left);








|







1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

    symbolsize = optionsize;
    if (calcsize > optionsize) {
        symbolsize = calcsize;
        if (optionsize != -1) {
            /* flag an error */
            error_number = ZINT_WARN_INVALID_OPTION;
            strcpy(symbol->errtxt, "Data does not fit in selected symbol size (E12)");
        }
    }

    // Now we know the symbol size we can handle the remaining data in the process buffer.
    symbols_left = matrixbytes[symbolsize] - binlen;
    binlen = dm200encode_remainder(binary, binlen, source, inputlen, last_mode, process_buffer, process_p, symbols_left);

1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311

    symbol->rows = H;
    symbol->width = W;

    return error_number;
}

int dmatrix(struct zint_symbol *symbol, unsigned char source[], const int length) {
    int error_number;

    if (symbol->option_1 <= 1) {
        /* ECC 200 */
        error_number = data_matrix_200(symbol, source, length);
    } else {
        /* ECC 000 - 140 */
        strcpy(symbol->errtxt, "Older Data Matrix standards are no longer supported");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }

    return error_number;
}







|




|


|





1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310

    symbol->rows = H;
    symbol->width = W;

    return error_number;
}

int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const int in_length) {
    int error_number;

    if (symbol->option_1 <= 1) {
        /* ECC 200 */
        error_number = data_matrix_200(symbol, source, in_length);
    } else {
        /* ECC 000 - 140 */
        strcpy(symbol->errtxt, "Older Data Matrix standards are no longer supported (E13)");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }

    return error_number;
}
Changes to jni/zint/backend/dmatrix.h.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#ifndef __IEC16022ECC200_H
#define __IEC16022ECC200_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], const int length);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#define MAXBARCODE 3116








|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#ifndef __IEC16022ECC200_H
#define __IEC16022ECC200_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern int data_matrix_200(struct zint_symbol *symbol, const unsigned char source[], const int length);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#define MAXBARCODE 3116

Added jni/zint/backend/dotcode.c.


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
/* dotcode.c - Handles DotCode */

/*
    libzint - the open source barcode library
    Copyright (C) 2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.    
 */

/* 
 * Attempts to encode DotCode according to AIMD013 Rev 1.34a, dated Feb 19, 2009
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#ifndef _MSC_VER
#include <stdint.h>
#else
#include "ms_stdint.h"
#include <malloc.h>
#endif
#include "common.h"
#include "gs1.h"

#define GF 113
#define PM 3

/* DotCode symbol character dot patterns, from Annex C */
static const int dot_patterns[113] = {
    0x155, 0x0ab, 0x0ad, 0x0b5, 0x0d5, 0x156, 0x15a, 0x16a, 0x1aa, 0x0ae,
    0x0b6, 0x0ba, 0x0d6, 0x0da, 0x0ea, 0x12b, 0x12d, 0x135, 0x14b, 0x14d,
    0x153, 0x159, 0x165, 0x169, 0x195, 0x1a5, 0x1a9, 0x057, 0x05b, 0x05d,
    0x06b, 0x06d, 0x075, 0x097, 0x09b, 0x09d, 0x0a7, 0x0b3, 0x0b9, 0x0cb,
    0x0cd, 0x0d3, 0x0d9, 0x0e5, 0x0e9, 0x12e, 0x136, 0x13a, 0x14e, 0x15c,
    0x166, 0x16c, 0x172, 0x174, 0x196, 0x19a, 0x1a6, 0x1ac, 0x1b2, 0x1b4,
    0x1ca, 0x1d2, 0x1d4, 0x05e, 0x06e, 0x076, 0x07a, 0x09e, 0x0bc, 0x0ce,
    0x0dc, 0x0e6, 0x0ec, 0x0f2, 0x0f4, 0x117, 0x11b, 0x11d, 0x127, 0x133,
    0x139, 0x147, 0x163, 0x171, 0x18b, 0x18d, 0x193, 0x199, 0x1a3, 0x1b1,
    0x1c5, 0x1c9, 0x1d1, 0x02f, 0x037, 0x03b, 0x03d, 0x04f, 0x067, 0x073,
    0x079, 0x08f, 0x0c7, 0x0e3, 0x0f1, 0x11e, 0x13c, 0x178, 0x18e, 0x19c,
    0x1b8, 0x1c6, 0x1cc
};

int get_dot(char Dots[], int Hgt, int Wid, int x, int y) {
    int retval = 0;

    if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) {
        if (Dots[(y * Wid) + x] == '1') {
            retval = 1;
        }
    }

    return retval;
}

/* Dot pattern scoring routine from Annex A */
int score_array(char Dots[], int Hgt, int Wid) {
    int x, y, worstedge, first, last, sum;

    sum = 0;
    first = -1;
    last = -1;

    // across the top edge, count printed dots and measure their extent
    for (x = 0; x < Wid; x += 2)
        if (get_dot(Dots, Hgt, Wid, x, 0)) {
            if (first < 0) {
                first = x;
            }
            last = x;
            sum++;
        }
    worstedge = sum + last - first;
    worstedge *= Hgt;

    sum = 0;
    first = -1;

    //across the bottom edge, ditto
    for (x = Wid & 1; x < Wid; x += 2)
        if (get_dot(Dots, Hgt, Wid, x, Hgt - 1)) {
            if (first < 0) {
                first = x;
            }
            last = x;
            sum++;
        }
    sum += last - first;
    sum *= Hgt;
    if (sum < worstedge) {
        worstedge = sum;
    }

    sum = 0;
    first = -1;

    //down the left edge, ditto
    for (y = 0; y < Hgt; y += 2)
        if (get_dot(Dots, Hgt, Wid, 0, y)) {
            if (first < 0) {
                first = y;
            }
            last = y;
            sum++;
        }
    sum += last - first;
    sum *= Wid;
    if (sum < worstedge) {
        worstedge = sum;
    }

    sum = 0;
    first = -1;

    //down the right edge, ditto
    for (y = Hgt & 1; y < Hgt; y += 2)
        if (get_dot(Dots, Hgt, Wid, Wid - 1, y)) {
            if (first < 0) {
                first = y;
            }
            last = y;
            sum++;
        }
    sum += last - first;
    sum *= Wid;
    if (sum < worstedge) {
        worstedge = sum;
    }

    // throughout the array, count the # of unprinted 5-somes (cross patterns)
    // plus the # of printed dots surrounded by 8 unprinted neighbors
    sum = 0;
    for (y = 0; y < Hgt; y++) {
        for (x = y & 1; x < Wid; x += 2) {
            if ((!get_dot(Dots, Hgt, Wid, x - 1, y - 1))
                    && (!get_dot(Dots, Hgt, Wid, x + 1, y - 1))
                    && (!get_dot(Dots, Hgt, Wid, x - 1, y + 1))
                    && (!get_dot(Dots, Hgt, Wid, x + 1, y + 1))
                    && ((!get_dot(Dots, Hgt, Wid, x, y))
                    || ((!get_dot(Dots, Hgt, Wid, x - 2, y))
                    && (!get_dot(Dots, Hgt, Wid, x, y - 2))
                    && (!get_dot(Dots, Hgt, Wid, x + 2, y))
                    && (!get_dot(Dots, Hgt, Wid, x, y + 2))))) {
                sum++;
            }
        }
    }

    return (worstedge - sum * sum);
}

//-------------------------------------------------------------------------
// "rsencode(nd,nc)" adds "nc" R-S check words to "nd" data words in wd[]
// employing Galois Field GF, where GF is prime, with a prime modulus of PM
//-------------------------------------------------------------------------

void rsencode(int nd, int nc, unsigned char *wd) {
    int i, j, k, nw, start, step, root[GF], c[GF];

    // Start by generating "nc" roots (antilogs):
    root[0] = 1;
    for (i = 1; i <= nc; i++)
        root[i] = (PM * root[i - 1]) % GF;

    // Here we compute how many interleaved R-S blocks will be needed
    nw = nd + nc;
    step = (nw + GF - 2) / (GF - 1);

    // ...& then for each such block:
    for (start = 0; start < step; start++) {
        int ND = (nd - start + step - 1) / step, NW = (nw - start + step - 1) / step, NC = NW - ND;

        // first compute the generator polynomial "c" of order "NC":
        for (i = 1; i <= NC; i++)
            c[i] = 0;
        c[0] = 1;

        for (i = 1; i <= NC; i++) {
            for (j = NC; j >= 1; j--) {
                c[j] = (GF + c[j] - (root[i] * c[j - 1]) % GF) % GF;
            }
        }

        // & then compute the corresponding checkword values into wd[]
        // ... (a) starting at wd[start] & (b) stepping by step
        for (i = ND; i < NW; i++)
            wd[start + i * step] = 0;
        for (i = 0; i < ND; i++) {
            k = (wd[start + i * step] + wd[start + ND * step]) % GF;
            for (j = 0; j < NC - 1; j++) {
                wd[start + (ND + j) * step] = (GF - ((c[j + 1] * k) % GF) + wd[start + (ND + j + 1) * step]) % GF;
            }
            wd[start + (ND + NC - 1) * step] = (GF - ((c[NC] * k) % GF)) % GF;
        }
        for (i = ND; i < NW; i++)
            wd[start + i * step] = (GF - wd[start + i * step]) % GF;
    }
}

/* Check if the next character is directly encodable in code set A (Annex F.II.D) */
int datum_a(const unsigned char source[], int position, int length) {
    int retval = 0;

    if (position < length) {
        if (source[position] <= 95) {
            retval = 1;
        }
    }

    return retval;
}

/* Check if the next character is directly encodable in code set B (Annex F.II.D) */
int datum_b(const unsigned char source[], int position, int length) {
    int retval = 0;

    if (position < length) {
        if (source[position] >= 32) {
            retval = 1;
        }

        switch (source[position]) {
            case 9: // HT
            case 28: // FS
            case 29: // GS
            case 30: // RS
                retval = 1;
        }

        if (position != length - 2) {
            if ((source[position] == 13) && (source[position + 1] == 10)) { // CRLF
                retval = 1;
            }
        }
    }

    return retval;
}

/* Check if the next characters are directly encodable in code set C (Annex F.II.D) */
int datum_c(const unsigned char source[], int position, int length) {
    int retval = 0;

    if (position < length - 2) {
        if (((source[position] >= '0') && (source[position] <= '9'))
                && ((source[position + 1] >= '0') && (source[position + 1] <= '9')))
            retval = 1;
    }

    return retval;
}

/* Returns how many consecutive digits lie immediately ahead (Annex F.II.A) */
int n_digits(const unsigned char source[], int position, int length) {
    int i;

    for (i = position; ((source[i] >= '0') && (source[i] <= '9')) && (i < length); i++);

    return i - position;
}

/* checks ahead for 10 or more digits starting "17xxxxxx10..." (Annex F.II.B) */
int seventeen_ten(const unsigned char source[], int position, int length) {
    int found = 0;

    if (n_digits(source, position, length) >= 10) {
        if (((source[position] == '1') && (source[position + 1] == '7'))
                && ((source[position + 8] == '1') && (source[position + 9] == '0'))) {
            found = 1;
        }
    }

    return found;
}

/*  checks how many characters ahead can be reached while datum_c is true,
 *  returning the resulting number of codewords (Annex F.II.E)
 */
int ahead_c(const unsigned char source[], int position, int length) {
    int count = 0;
    int i;

    for (i = position; (i < length) && datum_c(source, i, length); i += 2) {
        count++;
    }

    return count;
}

/* Annex F.II.F */
int try_c(const unsigned char source[], int position, int length) {
    int retval = 0;

    if (n_digits(source, position, length) > 0) {
        if (ahead_c(source, position, length) > ahead_c(source, position + 1, length)) {
            retval = ahead_c(source, position, length);
        }
    }

    return retval;
}

/* Annex F.II.G */
int ahead_a(const unsigned char source[], int position, int length) {
    int count = 0;
    int i;

    for (i = position; ((i < length) && datum_a(source, i, length))
            && (try_c(source, i, length) < 2); i++) {
        count++;
    }

    return count;
}

/* Annex F.II.H */
int ahead_b(const unsigned char source[], int position, int length) {
    int count = 0;
    int i;

    for (i = position; ((i < length) && datum_b(source, i, length))
            && (try_c(source, i, length) < 2); i++) {
        count++;
    }

    return count;
}

/* checks if the next character is in the range 128 to 255  (Annex F.II.I) */
int binary(const unsigned char source[], int position, int length) {
    int retval = 0;

    if (source[position] >= 128) {
        retval = 1;
    }

    return retval;
}

/* Analyse input data stream and encode using algorithm from Annex F */
int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char *codeword_array) {
    int input_position, array_length, i;
    char encoding_mode;
    int inside_macro, done;
    int debug = 0;
    int binary_buffer_size = 0;
    int lawrencium[6]; // Reversed radix 103 values

#if defined(_MSC_VER) && _MSC_VER == 1200
    uint64_t binary_buffer = 0;
#else
    uint64_t binary_buffer = 0ULL;
#endif

    input_position = 0;
    array_length = 0;
    encoding_mode = 'C';
    inside_macro = 0;

    if (symbol->output_options & READER_INIT) {
        codeword_array[array_length] = 109; // FNC3
        array_length++;
    }

    if (symbol->input_mode != GS1_MODE) {
        codeword_array[array_length] = 107; // FNC1
        array_length++;
    }

    if (symbol->eci > 3) {
        codeword_array[array_length] = 108; // FNC2
        array_length++;
        codeword_array[array_length] = symbol->eci;
        array_length++;
    }

    do {
        done = 0;

        /* Step A */
        if ((input_position == length - 2) && (inside_macro != 0) && (inside_macro != 100)) {
            // inside_macro only gets set to 97, 98 or 99 if the last two characters are RS/EOT
            input_position += 2;
            done = 1;
            if (debug) {
                printf("A ");
            }
        }

        if ((input_position == length - 1) && (inside_macro == 100)) {
            // inside_macro only gets set to 100 if the last character is EOT
            input_position++;
            done = 1;
            if (debug) {
                printf("A ");
            }
        }

        /* Step B1 */
        if ((!done) && (encoding_mode == 'C')) {
            if ((array_length == 0) && (length > 9)) {
                if ((source[input_position] == '[')
                        && (source[input_position + 1] == ')')
                        && (source[input_position + 2] == '>')
                        && (source[input_position + 3] == 30) // RS
                        && (source[length - 1] == 04)) { // EOT

                    codeword_array[array_length] = 106; // Latch B
                    array_length++;
                    encoding_mode = 'B';

                    if ((source[input_position + 6] == 29) && (source[length - 2] == 30)) { // GS/RS
                        if ((source[input_position + 4] == '0') && (source[input_position + 5] == '5')) {
                            codeword_array[array_length] = 97; // Macro
                            array_length++;
                            input_position += 7;
                            inside_macro = 97;
                            done = 1;
                            if (debug) {
                                printf("B1/1 ");
                            }
                        }

                        if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) {
                            codeword_array[array_length] = 98; // Macro
                            array_length++;
                            input_position += 7;
                            inside_macro = 98;
                            done = 1;
                            if (debug) {
                                printf("B1/2 ");
                            }
                        }

                        if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) {
                            codeword_array[array_length] = 99; // Macro
                            array_length++;
                            input_position += 7;
                            inside_macro = 99;
                            done = 1;
                            if (debug) {
                                printf("B1/3 ");
                            }
                        }
                    }

                    if (!done) {
                        codeword_array[array_length] = 100; // Macro
                        array_length++;
                        input_position += 4;
                        inside_macro = 100;
                        done = 1;
                        if (debug) {
                            printf("B1/4 ");
                        }
                    }
                }
            }
        }

        /* Step B2 */
        if ((!done) && (encoding_mode == 'C')) {
            if (seventeen_ten(source, input_position, length)) {
                codeword_array[array_length] = 100; // (17)...(10)
                array_length++;
                codeword_array[array_length] = ((source[input_position + 2] - '0') * 10) + (source[input_position + 3] - '0');
                array_length++;
                codeword_array[array_length] = ((source[input_position + 4] - '0') * 10) + (source[input_position + 5] - '0');
                array_length++;
                codeword_array[array_length] = ((source[input_position + 6] - '0') * 10) + (source[input_position + 7] - '0');
                array_length++;
                input_position += 10;
                done = 1;
                if (debug) {
                    printf("B2/1 ");
                }
            }
        }

        if ((!done) && (encoding_mode == 'C')) {
            if (datum_c(source, input_position, length) || ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE))) {
                if (source[input_position] == '[') {
                    codeword_array[array_length] = 107; // FNC1
                    input_position++;
                } else {
                    codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
                    input_position += 2;
                }
                array_length++;
                done = 1;
                if (debug) {
                    printf("B2/2 ");
                }
            }
        }

        /* Setp B3 */
        if ((!done) && (encoding_mode == 'C')) {
            if (binary(source, input_position, length)) {
                if (n_digits(source, input_position + 1, length) > 0) {
                    if ((source[input_position] - 128) < 32) {
                        codeword_array[array_length] = 110; // Bin Shift A
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 + 64;
                        array_length++;
                    } else {
                        codeword_array[array_length] = 111; // Bin Shift B
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 - 32;
                        array_length++;
                    }
                    input_position++;
                } else {
                    codeword_array[array_length] = 112; // Bin Latch
                    array_length++;
                    encoding_mode = 'X';
                }
                done = 1;
                if (debug) {
                    printf("B3 ");
                }
            }
        }

        /* Step B4 */
        if ((!done) && (encoding_mode == 'C')) {
            int m = ahead_a(source, input_position, length);
            int n = ahead_b(source, input_position, length);
            if (m > n) {
                codeword_array[array_length] = 101; // Latch A
                array_length++;
                encoding_mode = 'A';
            } else {
                if (n <= 4) {
                    codeword_array[array_length] = 101 + n; // nx Shift B
                    array_length++;

                    for (i = 0; i < n; i++) {
                        codeword_array[array_length] = source[input_position] - 32;
                        array_length++;
                        input_position++;
                    }
                } else {
                    codeword_array[array_length] = 106; // Latch B
                    array_length++;
                    encoding_mode = 'B';
                }
            }
            done = 1;
            if (debug) {
                printf("B4 ");
            }
        }

        /* Step C1 */
        if ((!done) && (encoding_mode == 'B')) {
            int n = try_c(source, input_position, length);

            if (n >= 2) {
                if (n <= 4) {
                    codeword_array[array_length] = 103 + (n - 2); // nx Shift C
                    array_length++;
                    for (i = 0; i < n; i++) {
                        codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
                        array_length++;
                        input_position += 2;
                    }
                } else {
                    codeword_array[array_length] = 106; // Latch C
                    array_length++;
                    encoding_mode = 'C';
                }
                done = 1;
                if (debug) {
                    printf("C1 ");
                }
            }
        }

        /* Step C2 */
        if ((!done) && (encoding_mode == 'B')) {
            if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) {
                codeword_array[array_length] = 107; // FNC1
                array_length++;
                input_position++;
                done = 1;
                if (debug) {
                    printf("C2/1 ");
                }
            } else {
                if (datum_b(source, input_position, length)) {
                    codeword_array[array_length] = source[input_position] - 32;
                    array_length++;
                    input_position++;
                    done = 1;
                    if (debug) {
                        printf("C2/2 ");
                    }
                }
            }
        }

        /* Step C3 */
        if ((!done) && (encoding_mode == 'B')) {
            if (binary(source, input_position, length)) {
                if (datum_b(source, input_position + 1, length)) {
                    if ((source[input_position] - 128) < 32) {
                        codeword_array[array_length] = 110; // Bin Shift A
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 + 64;
                        array_length++;
                    } else {
                        codeword_array[array_length] = 111; // Bin Shift B
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 - 32;
                        array_length++;
                    }
                    input_position++;
                } else {
                    codeword_array[array_length] = 112; // Bin Latch
                    array_length++;
                    encoding_mode = 'X';
                }
                done = 1;
                if (debug) {
                    printf("C3 ");
                }
            }
        }

        /* Step C4 */
        if ((!done) && (encoding_mode == 'B')) {
            if (ahead_a(source, input_position, length) == 1) {
                codeword_array[array_length] = 101; // Shift A
                array_length++;
                if (source[input_position] < 32) {
                    codeword_array[array_length] = source[input_position] + 64;
                } else {
                    codeword_array[array_length] = source[input_position] - 32;
                }
                array_length++;
                input_position++;
            } else {
                codeword_array[array_length] = 102; // Latch A
                array_length++;
                encoding_mode = 'A';
            }
            done = 1;
            if (debug) {
                printf("C4 ");
            }
        }

        /* Step D1 */
        if ((!done) && (encoding_mode == 'A')) {
            int n = try_c(source, input_position, length);
            if (n >= 2) {
                if (n <= 4) {
                    codeword_array[array_length] = 103 + (n - 2); // nx Shift C
                    array_length++;
                    for (i = 0; i < n; i++) {
                        codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
                        array_length++;
                        input_position += 2;
                    }
                } else {
                    codeword_array[array_length] = 106; // Latch C
                    array_length++;
                    encoding_mode = 'C';
                }
                done = 1;
                if (debug) {
                    printf("D1 ");
                }
            }
        }

        /* Step D2 */
        if ((!done) && (encoding_mode == 'A')) {
            if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) {
                codeword_array[array_length] = 107; // FNC1
                array_length++;
                input_position++;
                done = 1;
                if (debug) {
                    printf("D2/1 ");
                }
            } else {
                if (datum_a(source, input_position, length)) {
                    if (source[input_position] < 32) {
                        codeword_array[array_length] = source[input_position] + 64;
                    } else {
                        codeword_array[array_length] = source[input_position] - 32;
                    }
                    array_length++;
                    input_position++;
                    done = 1;
                    if (debug) {
                        printf("D2/2 ");
                    }
                }
            }
        }

        /* Step D3 */
        if ((!done) && (encoding_mode == 'A')) {
            if (binary(source, input_position, length)) {
                if (datum_a(source, input_position + 1, length)) {
                    if ((source[input_position] - 128) < 32) {
                        codeword_array[array_length] = 110; // Bin Shift A
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 + 64;
                        array_length++;
                    } else {
                        codeword_array[array_length] = 111; // Bin Shift B
                        array_length++;
                        codeword_array[array_length] = source[input_position] - 128 - 32;
                        array_length++;
                    }
                    input_position++;
                } else {
                    codeword_array[array_length] = 112; // Bin Latch
                    array_length++;
                    encoding_mode = 'X';
                }
                done = 1;
                if (debug) {
                    printf("D3 ");
                }
            }
        }

        /* Step D4 */
        if ((!done) && (encoding_mode == 'A')) {
            int n = ahead_b(source, input_position, length);

            if (n <= 6) {
                codeword_array[array_length] = 95 + n; // nx Shift B
                array_length++;
                for (i = 0; i < n; i++) {
                    codeword_array[array_length] = source[input_position] - 32;
                    array_length++;
                    input_position++;
                }
            } else {
                codeword_array[array_length] = 102; // Latch B
                array_length++;
                encoding_mode = 'B';
            }
            done = 1;
            if (debug) {
                printf("D4 ");
            }
        }

        /* Step E1 */
        if ((!done) && (encoding_mode == 'X')) {
            int n = try_c(source, input_position, length);

            if (n >= 2) {
                /* Empty binary buffer */
                for (i = 0; i < (binary_buffer_size + 1); i++) {
                    lawrencium[i] = binary_buffer % 103;
                    binary_buffer /= 103;
                }

                for (i = 0; i < (binary_buffer_size + 1); i++) {
                    codeword_array[array_length] = lawrencium[binary_buffer_size - i];
                    array_length++;
                }
                binary_buffer = 0;
                binary_buffer_size = 0;

                if (n <= 7) {
                    codeword_array[array_length] = 101 + n; // Interrupt for nx Shift C
                    array_length++;
                    for (i = 0; i < n; i++) {
                        codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
                        array_length++;
                        input_position += 2;
                    }
                } else {
                    codeword_array[array_length] = 111; // Terminate with Latch to C
                    array_length++;
                    encoding_mode = 'C';
                }
                done = 1;
                if (debug) {
                    printf("E1 ");
                }
            }
        }

        /* Step E2 */
        /* Section 5.2.1.1 para D.2.i states:
         * "Groups of six codewords, each valued between 0 and 102, are radix converted from
         * base 103 into five base 259 values..."
         */
        if ((!done) && (encoding_mode == 'X')) {
            if (binary(source, input_position, length)
                    || binary(source, input_position + 1, length)
                    || binary(source, input_position + 2, length)
                    || binary(source, input_position + 3, length)) {
                binary_buffer *= 259;
                binary_buffer += source[input_position];
                binary_buffer_size++;

                if (binary_buffer_size == 5) {
                    for (i = 0; i < 6; i++) {
                        lawrencium[i] = binary_buffer % 103;
                        binary_buffer /= 103;
                    }

                    for (i = 0; i < 6; i++) {
                        codeword_array[array_length] = lawrencium[5 - i];
                        array_length++;
                    }
                    binary_buffer = 0;
                    binary_buffer_size = 0;
                }
                input_position++;
                done = 1;
                if (debug) {
                    printf("E2 ");
                }
            }
        }

        /* Step E3 */
        if ((!done) && (encoding_mode == 'X')) {
            /* Empty binary buffer */
            for (i = 0; i < (binary_buffer_size + 1); i++) {
                lawrencium[i] = binary_buffer % 103;
                binary_buffer /= 103;
            }

            for (i = 0; i < (binary_buffer_size + 1); i++) {
                codeword_array[array_length] = lawrencium[binary_buffer_size - i];
                array_length++;
            }
            binary_buffer = 0;
            binary_buffer_size = 0;

            if (ahead_a(source, input_position, length) > ahead_b(source, input_position, length)) {
                codeword_array[array_length] = 109; // Terminate with Latch to A
                encoding_mode = 'A';
            } else {
                codeword_array[array_length] = 110; // Terminate with Latch to B
                encoding_mode = 'B';
            }
            array_length++;
            done = 1;
            if (debug) {
                printf("E3 ");
            }
        }
    } while (input_position < length);

    if (debug) {
        printf("\n\n");
    }

    return array_length;
}

/* Convert codewords to binary data stream */
static size_t make_dotstream(unsigned char masked_array[], int array_length, char dot_stream[]) {
    int i, j;
    int mask = 0x100;

    dot_stream[0] = '\0';

    /* Mask value is encoded as two dots */
    switch (masked_array[0]) {
        case 0:
            strcat(dot_stream, "00");
            break;
        case 1:
            strcat(dot_stream, "01");
            break;
        case 2:
            strcat(dot_stream, "10");
            break;
        case 3:
            strcat(dot_stream, "11");
            break;
    }

    /* The rest of the data uses 9-bit dot patterns from Annex C */
    for (i = 1; i < array_length; i++) {
        for (j = 0; j < 9; j++) {
            if (dot_patterns[masked_array[i]] & (mask >> j)) {
                strcat(dot_stream, "1");
            } else {
                strcat(dot_stream, "0");
            }
        }
    }

    return strlen(dot_stream);
}

/* Determines if a given dot is a reserved corner dot 
 * to be used by one of the last six bits 
 */
int is_corner(int column, int row, int width, int height) {
    int corner = 0;

    /* Top Left */
    if ((column == 0) && (row == 0)) {
        corner = 1;
    }

    /* Top Right */
    if (height % 2) {
        if (((column == width - 2) && (row == 0))
                || ((column == width - 1) && (row == 1))) {
            corner = 1;
        }
    } else {
        if ((column == width - 1) && (row == 0)) {
            corner = 1;
        }
    }

    /* Bottom Left */
    if (height % 2) {
        if ((column == 0) && (row == height - 1)) {
            corner = 1;
        }
    } else {
        if (((column == 0) && (row == height - 2))
                || ((column == 1) && (row == height - 1))) {
            corner = 1;
        }
    }

    /* Bottom Right */
    if (((column == width - 2) && (row == height - 1))
            || ((column == width - 1) && (row == height - 2))) {
        corner = 1;
    }

    return corner;
}

/* Place the dots in the symbol*/
void fold_dotstream(char dot_stream[], int width, int height, char dot_array[]) {
    int column, row;
    int input_position = 0;

    if (height % 2) {
        /* Horizontal folding */
        for (row = 0; row < height; row++) {
            for (column = 0; column < width; column++) {
                if (!((column + row) % 2)) {
                    if (is_corner(column, row, width, height)) {
                        dot_array[(row * width) + column] = 'C';
                    } else {
                        dot_array[((height - row - 1) * width) + column] = dot_stream[input_position];
                        input_position++;
                    }
                } else {
                    dot_array[((height - row - 1) * width) + column] = ' '; // Non-data position
                }
            }
        }

        /* Corners */
        dot_array[width - 2] = dot_stream[input_position];
        input_position++;
        dot_array[(height * width) - 2] = dot_stream[input_position];
        input_position++;
        dot_array[(width * 2) - 1] = dot_stream[input_position];
        input_position++;
        dot_array[((height - 1) * width) - 1] = dot_stream[input_position];
        input_position++;
        dot_array[0] = dot_stream[input_position];
        input_position++;
        dot_array[(height - 1) * width] = dot_stream[input_position];
    } else {
        /* Vertical folding */
        for (column = 0; column < width; column++) {
            for (row = 0; row < height; row++) {
                if (!((column + row) % 2)) {
                    if (is_corner(column, row, width, height)) {
                        dot_array[(row * width) + column] = 'C';
                    } else {
                        dot_array[(row * width) + column] = dot_stream[input_position];
                        input_position++;
                    }
                } else {
                    dot_array[(row * width) + column] = ' '; // Non-data position
                }
            }
        }

        /* Corners */
        dot_array[((height - 1) * width) - 1] = dot_stream[input_position];
        input_position++;
        dot_array[(height - 2) * width] = dot_stream[input_position];
        input_position++;
        dot_array[(height * width) - 2] = dot_stream[input_position];
        input_position++;
        dot_array[((height - 1) * width) + 1] = dot_stream[input_position];
        input_position++;
        dot_array[width - 1] = dot_stream[input_position];
        input_position++;
        dot_array[0] = dot_stream[input_position];
    }
}

int dotcode(struct zint_symbol *symbol, const unsigned char source[], int length) {
    int i, j, k;
    size_t jc;
    int data_length, ecc_length;
    int min_dots, n_dots;
    int height, width, pad_chars;
    int mask_score[4];
    int weight;
    size_t dot_stream_length;
    int high_score, best_mask;
    int debug = 0;

#ifndef _MSC_VER
    unsigned char codeword_array[length * 3];
    unsigned char masked_codeword_array[length * 3];
#else
    char* dot_stream;
    char* dot_array;
    unsigned char* codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char));
    unsigned char* masked_codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char));
#endif /* _MSC_VER */

    data_length = dotcode_encode_message(symbol, source, length, codeword_array);

    ecc_length = 3 + (data_length / 2);

    if (debug) {
        printf("Codeword length = %d, ECC length = %d\n", data_length, ecc_length);
    }

    min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2;

    if (symbol->option_2 == 0) {

        height = (int) sqrt(2.0 * min_dots);
        if (height % 2) {
            height++;
        }

        width = (2 * min_dots) / height;
        if (!(width % 2)) {
            width++;
        }

    } else {
        width = symbol->option_2;

        height = (2 * min_dots) / width;

        if (!((width + height) % 2)) {
            height++;
        }
    }

    if ((height > 200) || (width > 200)) {
        strcpy(symbol->errtxt, "Specified symbol size is too large (E20)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    n_dots = (height * width) / 2;

#ifndef _MSC_VER
    char dot_stream[height * width * 3];
    char dot_array[width * height * sizeof (char) ];
#else
    dot_stream = (char *) _alloca(height * width * 3);
    if (!dot_stream) return ZINT_ERROR_MEMORY;

    dot_array = (char *) _alloca(width * height * sizeof (char));
    if (!dot_array) return ZINT_ERROR_MEMORY;
#endif

    /* Add pad characters */
    for (pad_chars = 0; 9 * ((data_length + pad_chars + 3 + ((data_length + pad_chars) / 2)) + 2) < n_dots; pad_chars++);

    if (pad_chars > 0) {
        codeword_array[data_length] = 109; // Latch to Code Set A
        data_length++;
        pad_chars--;
    }

    for (i = 0; i < pad_chars; i++) {
        codeword_array[data_length] = 106; // Pad
        data_length++;
    }

    if (data_length > 450) {
        // Larger data sets than this cause rsencode() to throw SIGSEGV
        // This should probably be fixed by somebody who understands what rsencode() does...
        strcpy(symbol->errtxt, "Input too long (E21)");
        return ZINT_ERROR_TOO_LONG;
    }

    ecc_length = 3 + (data_length / 2);

    /* Evaluate data mask options */
    for (i = 0; i < 4; i++) {
        switch (i) {
            case 0:
                masked_codeword_array[0] = 0;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = codeword_array[j];
                }
                break;
            case 1:
                weight = 0;
                masked_codeword_array[0] = 1;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
                    weight += 3;
                }
                break;
            case 2:
                weight = 0;
                masked_codeword_array[0] = 2;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
                    weight += 7;
                }
                break;
            case 3:
                weight = 0;
                masked_codeword_array[0] = 3;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
                    weight += 17;
                }
                break;
        }

        rsencode(data_length + 1, ecc_length, masked_codeword_array);

        dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);

        /* Add pad bits */
        for (jc = dot_stream_length; jc < n_dots; jc++) {
            strcat(dot_stream, "1");
        }

        fold_dotstream(dot_stream, width, height, dot_array);

        mask_score[i] = score_array(dot_array, height, width);

        if (debug) {
            printf("Mask %d score is %d\n", i, mask_score[i]);
        }
    }

    high_score = mask_score[0];
    best_mask = 0;

    for (i = 1; i < 4; i++) {
        if (mask_score[i] > high_score) {
            high_score = mask_score[i];
            best_mask = i;
        }
    }

    if (best_mask != 3) {
        /* Reprocess to get symbol with best mask */
        switch (best_mask) {
            case 0:
                masked_codeword_array[0] = 0;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = codeword_array[j];
                }
                break;
            case 1:
                weight = 0;
                masked_codeword_array[0] = 1;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
                    weight += 3;
                }
                break;
            case 2:
                weight = 0;
                masked_codeword_array[0] = 2;
                for (j = 0; j < data_length; j++) {
                    masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
                    weight += 7;
                }
                break;
        }

        rsencode(data_length + 1, ecc_length, masked_codeword_array);
        dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);

        /* Add pad bits */
        for (jc = dot_stream_length; jc < n_dots; jc++) {
            strcat(dot_stream, "1");
        }

        fold_dotstream(dot_stream, width, height, dot_array);
    } /* else { the version with the best mask is already in memory } */

    if (debug) {
        for (k = 0; k < height; k++) {
            for (j = 0; j < width; j++) {
                printf("%c", dot_array[(k * width) + j]);
            }
            printf("\n");
        }
    }

    /* Copy values to symbol */
    symbol->width = width;
    symbol->rows = height;

    for (k = 0; k < height; k++) {
        for (j = 0; j < width; j++) {
            if (dot_array[(k * width) + j] == '1') {
                set_module(symbol, k, j);
            }
        }
        symbol->row_height[k] = 1;
    }

    if (!(symbol->output_options & BARCODE_DOTTY_MODE)) {
        symbol->output_options += BARCODE_DOTTY_MODE;
    }

    return 0;
}
Added jni/zint/backend/eci.c.










































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*  eci.c - Extended Channel Interpretations

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "eci.h"
#include "zint.h"
#ifdef _MSC_VER
#include <malloc.h>
#endif

/* Convert Unicode to other character encodings */
int utf_to_eci(int eci, const unsigned char source[], unsigned char dest[], int *length) {
    int glyph;
    int bytelen;
    int in_posn;
    int out_posn;
    int ext;
    int done;

    if (eci == 26) {
        /* Unicode mode, do not process - just copy data across */
        for (in_posn = 0; in_posn < *length; in_posn++) {
            dest[in_posn] = source[in_posn];
        }
        dest[*length] = '\0';
        return 0;
    }

    in_posn = 0;
    out_posn = 0;
    do {
        /* Single byte (ASCII) character */
        bytelen = 1;
        glyph = (int) source[in_posn];

        if ((source[in_posn] >= 0x80) && (source[in_posn] < 0xc0)) {
            /* Something has gone wrong, abort */
            return ZINT_ERROR_INVALID_DATA;
        }

        if ((source[in_posn] >= 0xc0) && (source[in_posn] < 0xe0)) {
            /* Two-byte character */
            bytelen = 2;
            glyph = (source[in_posn] & 0x1f) << 6;

            if (*length < (in_posn + 2)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 1] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            glyph += (source[in_posn + 1] & 0x3f);
        }

        if ((source[in_posn] >= 0xe0) && (source[in_posn] < 0xf0)) {
            /* Three-byte character */
            bytelen = 3;
            glyph = (source[in_posn] & 0x0f) << 12;

            if (*length < (in_posn + 2)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (*length < (in_posn + 3)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 1] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 2] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            glyph += (source[in_posn + 1] & 0x3f) << 6;
            glyph += (source[in_posn + 2] & 0x3f);
        }

        if ((source[in_posn] >= 0xf0) && (source[in_posn] < 0xf7)) {
            /* Four-byte character */
            bytelen = 4;
            glyph = (source[in_posn] & 0x07) << 18;

            if (*length < (in_posn + 2)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (*length < (in_posn + 3)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (*length < (in_posn + 4)) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 1] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 2] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            if (source[in_posn + 3] > 0xc0) {
                return ZINT_ERROR_INVALID_DATA;
            }

            glyph += (source[in_posn + 1] & 0x3f) << 12;
            glyph += (source[in_posn + 2] & 0x3f) << 6;
            glyph += (source[in_posn + 3] & 0x3f);
        }

        if (source[in_posn] >= 0xf7) {
            /* More than 4 bytes not supported */
            return ZINT_ERROR_INVALID_DATA;
        }

        if (glyph < 128) {
            dest[out_posn] = glyph;
        } else {
            done = 0;
            for (ext = 0; ext < 128; ext++) {
                switch (eci) {
                    case 3: // Latin-1
                        if (glyph == iso_8859_1[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 4: // Latin-2
                        if (glyph == iso_8859_2[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 5: // Latin-3
                        if (glyph == iso_8859_3[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 6: // Latin-4
                        if (glyph == iso_8859_4[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 7: // Latin/Cyrillic
                        if (glyph == iso_8859_5[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 8: // Latin/Arabic
                        if (glyph == iso_8859_6[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 9: // Latin/Greek
                        if (glyph == iso_8859_7[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 10: // Latin/Hebrew
                        if (glyph == iso_8859_8[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 11: // Latin-5
                        if (glyph == iso_8859_9[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 12: // Latin-6
                        if (glyph == iso_8859_10[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 13: // Latin/Thai
                        if (glyph == iso_8859_11[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 15: // Latin-7
                        if (glyph == iso_8859_13[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 16: // Latin-8
                        if (glyph == iso_8859_14[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 17: // Latin-9
                        if (glyph == iso_8859_15[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 18: // Latin-10
                        if (glyph == iso_8859_16[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 21: // Windows-1250
                        if (glyph == windows_1250[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 22: // Windows-1251
                        if (glyph == windows_1251[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 23: // Windows-1252
                        if (glyph == windows_1252[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    case 24: // Windows-1256
                        if (glyph == windows_1256[ext]) {
                            dest[out_posn] = ext + 128;
                            done = 1;
                        }
                        break;
                    default:
                        break;
                }
            }

            if (!(done)) {
                return ZINT_ERROR_INVALID_DATA;
            }
        }

        in_posn += bytelen;
        out_posn++;
    } while (in_posn < *length);
    dest[out_posn] = '\0';
    *length = out_posn;

    return 0;
}

/* Find the lowest ECI mode which will encode a given set of Unicode text */
int get_best_eci(unsigned char source[], int length) {
    int eci = 3;

#ifndef _MSC_VER
    unsigned char local_source[length + 1];
#else
    unsigned char *local_source = (unsigned char*) _alloca(length + 1);
#endif

    do {
        if (utf_to_eci(eci, source, local_source, &length) == 0) {
            return eci;
        }
        eci++;
    } while (eci < 25);

    return 26; // If all of these fail, use Unicode!
}

Added jni/zint/backend/eci.h.
























































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*  eci.c - Extended Channel Interpretations to Unicode tables

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#ifndef ECI_H
#define ECI_H

#ifdef __cplusplus
extern "C" {
#endif

    static const int iso_8859_1[] = {// Latin alphabet No. 1
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
        0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
    };

    static const int iso_8859_2[] = {// Latin alphabet No. 2
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
        0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
        0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
        0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
        0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
        0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
    };

    static const int iso_8859_3[] = {// Latin alphabet No. 3
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
        0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
        0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9
    };

    static const int iso_8859_4[] = {// Latin alphabet No. 4
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x012b, 0x013b, 0x00a7, 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
        0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
        0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
        0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
        0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
        0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9
    };

    static const int iso_8859_5[] = {// Latin/Cyrillic alphabet
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
        0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
        0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
        0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
        0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
        0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f
    };

    static const int iso_8859_6[] = {// Latin/Arabic alphabet
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
        0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
        0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
        0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
    };

    static const int iso_8859_7[] = {// Latin/Greek alphabet
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
        0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
        0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
        0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
        0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000
    };

    static const int iso_8859_8[] = {// Latin/Hebrew alphabet
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
        0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
        0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000
    };

    static const int iso_8859_9[] = {// Latin alphabet No. 5
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
        0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff
    };

    static const int iso_8859_10[] = {// Latin alphabet No. 6
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x012b, 0x0136, 0x00a7, 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
        0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
        0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
        0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
        0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
        0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138
    };

    static const int iso_8859_11[] = {// Latin/Thai alphabet
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
        0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
        0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
        0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e36, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
        0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
        0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000
    };

    static const int iso_8859_13[] = {// Latin alphabet No. 7
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
        0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
        0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
        0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
        0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019
    };

    static const int iso_8859_14[] = {// Latin alphabet No. 8 (Celtic)
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
        0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
        0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff
    };

    static const int iso_8859_15[] = {// Latin alphabet No. 9
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
        0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
    };

    static const int iso_8859_16[] = {// Latin alphabet No. 10
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
        0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
        0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff
    };

    static const int windows_1250[] = {
        0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
        0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
        0x00a0, 0x02c7, 0x02db, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
        0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
        0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
        0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
        0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
        0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
    };

    static const int windows_1251[] = {
        0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
        0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
        0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
        0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
        0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
        0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
        0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
        0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f
    };

    static const int windows_1252[] = {
        0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
        0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178,
        0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
        0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
        0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
        0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
        0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
    };

    static const int windows_1256[] = {
        0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
        0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba,
        0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
        0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f,
        0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
        0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643,
        0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef,
        0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2
    };

#ifdef __cplusplus
}
#endif

#endif /* ECI_H */

Added jni/zint/backend/gb18030.h.

more than 10,000 changes

Added jni/zint/backend/gif.c.




































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
/* gif.c - Handles output to gif file */

/*
    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include <math.h>
#ifdef _MSC_VER
#include <io.h>
#include <fcntl.h>
#include <malloc.h>
#endif

#define SSET	"0123456789ABCDEF"

/* Index of transparent color, -1 for no transparent color
 * This might be set into a variable if transparency is activated as an option
 */
#define TRANSPARENT_INDEX (-1)

/* Used bit depth, may be changed for bigger pallet in future */
#define DESTINATION_IMAGE_BITS 1
#include <stdlib.h>

typedef struct s_statestruct {
    unsigned char * pOut;
    unsigned char *pIn;
    unsigned int InLen;
    unsigned int OutLength;
    unsigned int OutPosCur;
    unsigned int OutByteCountPos;
    unsigned short ClearCode;
    unsigned short FreeCode;
    char fByteCountByteSet;
    unsigned char OutBitsFree;
    unsigned short NodeAxon[4096];
    unsigned short NodeNext[4096];
    unsigned char NodePix[4096];
} statestruct;

static char BufferNextByte(statestruct *pState) {
    (pState->OutPosCur)++;
    /* Check if this position is a byte count position
     * fg_f_bytecountbyte_set indicates, if byte count position bytes should be
     * inserted in general.
     * If this is true, and the distance to the last byte count position is 256
     * (e.g. 255 bytes in between), a byte count byte is inserted, and the value
     * of the last one is set to 255.
     * */
    if (pState->fByteCountByteSet && (pState->OutByteCountPos + 256 == pState->OutPosCur)) {
        (pState->pOut)[pState->OutByteCountPos] = 255;
        pState->OutByteCountPos = pState->OutPosCur;
        (pState->OutPosCur)++;
    }
    if (pState->OutPosCur >= pState->OutLength)
        return 1;
    (pState->pOut)[pState->OutPosCur] = 0x00;
    return 0;
}

static char AddCodeToBuffer(statestruct *pState, unsigned short CodeIn, unsigned char CodeBits) {
    /* Check, if we may fill up the current byte completely */
    if (CodeBits >= pState->OutBitsFree) {
        (pState->pOut)[pState->OutPosCur] |= (unsigned char)
                (CodeIn << (8 - pState->OutBitsFree));
        if (BufferNextByte(pState))
            return -1;
        CodeIn = (unsigned short) (CodeIn >> pState->OutBitsFree);
        CodeBits -= pState->OutBitsFree;
        pState->OutBitsFree = 8;
        /* Write a full byte if there are at least 8 code bits left */
        if (CodeBits >= pState->OutBitsFree) {
            (pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn;
            if (BufferNextByte(pState))
                return -1;
            CodeIn = (unsigned short) (CodeIn >> 8);
            CodeBits -= 8;
        }
    }
    /* The remaining bits of CodeIn fit in the current byte. */
    if (CodeBits > 0) {
        (pState->pOut)[pState->OutPosCur] |= (unsigned char)
                (CodeIn << (8 - pState->OutBitsFree));
        pState->OutBitsFree -= CodeBits;
    }
    return 0;
}

static void FlushStringTable(statestruct *pState) {
    unsigned short Pos;
    for (Pos = 0; Pos < pState->ClearCode; Pos++) {
        (pState->NodeAxon)[Pos] = 0;
    }
}

unsigned short FindPixelOutlet(statestruct *pState, unsigned short HeadNode, unsigned char Byte) {
    unsigned short Outlet;

    Outlet = (pState->NodeAxon)[HeadNode];
    while (Outlet) {
        if ((pState->NodePix)[Outlet] == Byte)
            return Outlet;
        Outlet = (pState->NodeNext)[Outlet];
    }
    return 0;
}

static char NextCode(statestruct *pState, unsigned char * pPixelValueCur, unsigned char CodeBits) {
    unsigned short UpNode;
    unsigned short DownNode;
    /* start with the root node for last pixel chain */
    UpNode = *pPixelValueCur;
    if ((pState->InLen) == 0)
        return AddCodeToBuffer(pState, UpNode, CodeBits);

    *pPixelValueCur = (*(pState->pIn)) - '0';
    (pState->pIn)++;
    (pState->InLen)--;
    /* Follow the string table and the data stream to the end of the longest string that has a code */
    while (0 != (DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur))) {
        UpNode = DownNode;
        if ((pState->InLen) == 0)
            return AddCodeToBuffer(pState, UpNode, CodeBits);

        *pPixelValueCur = (*(pState->pIn)) - '0';
        (pState->pIn)++;
        (pState->InLen)--;
    }
    /* Submit 'UpNode' which is the code of the longest string */
    if (AddCodeToBuffer(pState, UpNode, CodeBits))
        return -1;
    /* ... and extend the string by appending 'PixelValueCur' */
    /* Create a successor node for 'PixelValueCur' whose code is 'freecode' */
    (pState->NodePix)[pState->FreeCode] = *pPixelValueCur;
    (pState->NodeAxon)[pState->FreeCode] = (pState->NodeNext)[pState->FreeCode] = 0;
    /* ...and link it to the end of the chain emanating from fg_axon[UpNode]. */
    DownNode = (pState->NodeAxon)[UpNode];
    if (!DownNode) {
        (pState->NodeAxon)[UpNode] = pState->FreeCode;
    } else {
        while ((pState->NodeNext)[DownNode]) {
            DownNode = (pState->NodeNext)[DownNode];
        }
        (pState->NodeNext)[DownNode] = pState->FreeCode;
    }
    return 1;
}

int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int InLen) {
    unsigned char PixelValueCur;
    unsigned char CodeBits;
    unsigned short Pos;
    statestruct State;

    State.pIn = pIn;
    State.InLen = InLen;
    State.pOut = pOut;
    State.OutLength = OutLength;
    // > Get first data byte
    if (State.InLen == 0)
        return 0;

    PixelValueCur = (unsigned char) ((*(State.pIn)) - '0');
    (State.pIn)++;
    (State.InLen)--;
    CodeBits = 3;
    State.ClearCode = 4;
    State.FreeCode = 6;
    State.OutBitsFree = 8;
    State.OutPosCur = -1;
    State.fByteCountByteSet = 0;

    if (BufferNextByte(&State))
        return 0;

    for (Pos = 0; Pos < State.ClearCode; Pos++)
        State.NodePix[Pos] = (unsigned char) Pos;

    FlushStringTable(&State);

    /* Write what the GIF specification calls the "code size". */
    (State.pOut)[State.OutPosCur] = 2;
    /* Reserve first bytecount byte */
    if (BufferNextByte(&State))
        return 0;
    State.OutByteCountPos = State.OutPosCur;
    if (BufferNextByte(&State))
        return 0;
    State.fByteCountByteSet = 1;
    /* Submit one 'ClearCode' as the first code */
    if (AddCodeToBuffer(&State, State.ClearCode, CodeBits))
        return 0;

    for (;;) {
        char Res;
        /* generate and save the next code, which may consist of multiple input pixels. */
        Res = NextCode(&State, &PixelValueCur, CodeBits);
        if (Res < 0)
            return 0;
        //* Check for end of data stream */
        if (!Res) {
            /* submit 'eoi' as the last item of the code stream */
            if (AddCodeToBuffer(&State, (unsigned short) (State.ClearCode + 1), CodeBits))
                return 0;
            State.fByteCountByteSet = 0;
            if (State.OutBitsFree < 8) {
                if (BufferNextByte(&State))
                    return 0;
            }
            // > Update last bytecount byte;
            if (State.OutByteCountPos < State.OutPosCur) {
                (State.pOut)[State.OutByteCountPos] = (unsigned char) (State.OutPosCur - State.OutByteCountPos - 1);
            }
            State.OutPosCur++;
            return State.OutPosCur;
        }
        /* Check for currently last code */
        if (State.FreeCode == (1U << CodeBits))
            CodeBits++;
        State.FreeCode++;
        /* Check for full stringtable */
        if (State.FreeCode == 0xfff) {
            FlushStringTable(&State);
            if (AddCodeToBuffer(&State, State.ClearCode, CodeBits))
                return 0;

            CodeBits = (unsigned char) (1 + 2);
            State.FreeCode = (unsigned short) (State.ClearCode + 2);
        }
    }
}

int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
    char outbuf[10];
    FILE *gif_file;
    unsigned short usTemp;
    int byte_out;
#ifdef _MSC_VER
    char * lzwoutbuf;
#endif

#ifndef _MSC_VER
    char lzwoutbuf[symbol->bitmap_height * symbol->bitmap_width];
#else
    lzwoutbuf = (char *) _alloca((symbol->bitmap_height * symbol->bitmap_width) * sizeof (char));
#endif /* _MSC_VER */

    /* Open output file in binary mode */
    if ((symbol->output_options & BARCODE_STDOUT) != 0) {
#ifdef _MSC_VER
        if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
#endif
        gif_file = stdout;
    } else {
        if (!(gif_file = fopen(symbol->outfile, "wb"))) {
            strcpy(symbol->errtxt, "Can't open output file (F10)");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }
    /*ImageWidth = 2;
    ImageHeight = 2;
    rotated_bitmap[0] = 1;
    rotated_bitmap[1] = 1;
    rotated_bitmap[2] = 0;
    rotated_bitmap[3] = 0;
     */

    /* GIF signature (6) */
    memcpy(outbuf, "GIF87a", 6);
    if (TRANSPARENT_INDEX != -1)
        outbuf[4] = '9';
    fwrite(outbuf, 6, 1, gif_file);
    /* Screen Descriptor (7) */
    /* Screen Width */
    usTemp = (unsigned short) symbol->bitmap_width;
    outbuf[0] = (unsigned char) (0xff & usTemp);
    outbuf[1] = (unsigned char) ((0xff00 & usTemp) / 0x100);
    /* Screen Height */
    usTemp = (unsigned short) symbol->bitmap_height;
    outbuf[2] = (unsigned char) (0xff & usTemp);
    outbuf[3] = (unsigned char) ((0xff00 & usTemp) / 0x100);
    /* write ImageBits-1 to the three least significant bits of byte 5  of
     * the Screen Descriptor
     */
    outbuf[4] = (unsigned char) (0xf0 | (0x7 & (DESTINATION_IMAGE_BITS - 1)));
    /*  Background color = colortable index 0 */
    outbuf[5] = 0x00;
    /* Byte 7 must be 0x00  */
    outbuf[6] = 0x00;
    fwrite(outbuf, 7, 1, gif_file);
    /* Global Color Table (6) */
    /* RGB 0 color */
    outbuf[0] = (unsigned char) (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    outbuf[1] = (unsigned char) (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    outbuf[2] = (unsigned char) (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
    /* RGB 1 color */
    outbuf[3] = (unsigned char) (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    outbuf[4] = (unsigned char) (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    outbuf[5] = (unsigned char) (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    fwrite(outbuf, 6, 1, gif_file);

    /* Graphic control extension (8) */
    /* A graphic control extension block is used for overlay gifs.
     * This is necessary to define a transparent color.
     */
    if (TRANSPARENT_INDEX != -1) {
        /* Extension Introducer = '!' */
        outbuf[0] = '\x21';
        /* Graphic Control Label */
        outbuf[1] = '\xf9';
        /* Block Size */
        outbuf[2] = 4;
        /* Packet fields:
         * 3 Reserved
         * 3 Disposal Method: 0 No Action, 1 No Dispose, 2: Background, 3: Prev.
         * 1 User Input Flag: 0: no user input, 1: user input
         * 1 Transparent Color Flag: 0: No Transparency, 1: Transparency index
         */
        outbuf[3] = 1;
        /* Delay Time */
        outbuf[4] = 0;
        outbuf[5] = 0;
        /* Transparent Color Index */
        outbuf[6] = (unsigned char) TRANSPARENT_INDEX;
        /* Block Terminator */
        outbuf[7] = 0;
        fwrite(outbuf, 8, 1, gif_file);
    }
    /* Image Descriptor */
    /* Image separator character = ',' */
    outbuf[0] = 0x2c;
    /* "Image Left" */
    outbuf[1] = 0x00;
    outbuf[2] = 0x00;
    /* "Image Top" */
    outbuf[3] = 0x00;
    outbuf[4] = 0x00;
    /* Image Width (low byte first) */
    outbuf[5] = (unsigned char) (0xff & symbol->bitmap_width);
    outbuf[6] = (unsigned char) ((0xff00 & symbol->bitmap_width) / 0x100);
    /* Image Height */
    outbuf[7] = (unsigned char) (0xff & symbol->bitmap_height);
    outbuf[8] = (unsigned char) ((0xff00 & symbol->bitmap_height) / 0x100);

    /* Byte 10 contains the interlaced flag and
     * information on the local color table.
     * There is no local color table if its most significant bit is reset.
     */
    outbuf[9] = (unsigned char) (0 | (0x7 & (DESTINATION_IMAGE_BITS - 1)));
    fwrite(outbuf, 10, 1, gif_file);

    /* call lzw encoding */
    byte_out = gif_lzw(
            (unsigned char *) lzwoutbuf,
            symbol->bitmap_height * symbol->bitmap_width,
            (unsigned char *) pixelbuf,
            symbol->bitmap_height * symbol->bitmap_width);
    if (byte_out <= 0) {
        fclose(gif_file);
        return ZINT_ERROR_MEMORY;
    }
    fwrite(lzwoutbuf, byte_out, 1, gif_file);

    /* GIF terminator */
    fputc('\x3b', gif_file);
    fclose(gif_file);

    return 0;
}
Changes to jni/zint/backend/gridmtx.c.
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
            strcat(binary, "1");
        } else {
            strcat(binary, "0");
        }
    }
}

int gm_encode(int gbdata[], int length, char binary[], int reader) {
    /* Create a binary stream representation of the input data.
       7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
       Mixed numerals and latters, Control characters and 8-bit binary data */
    int sp, current_mode, next_mode, last_mode, glyph = 0, q;
    int c1, c2, done;
    int p = 0, ppos;
    int numbuf[3], punt = 0;







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
            strcat(binary, "1");
        } else {
            strcat(binary, "0");
        }
    }
}

int gm_encode(int gbdata[], int length, char binary[], int reader, int eci) {
    /* Create a binary stream representation of the input data.
       7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
       Mixed numerals and latters, Control characters and 8-bit binary data */
    int sp, current_mode, next_mode, last_mode, glyph = 0, q;
    int c1, c2, done;
    int p = 0, ppos;
    int numbuf[3], punt = 0;
366
367
368
369
370
371
372











373
374
375
376
377
378
379
    current_mode = 0;
    last_mode = 0;
    number_pad_posn = 0;

    if (reader) {
        strcat(binary, "1010"); /* FNC3 - Reader Initialisation */
    }












    do {
        next_mode = seek_forward(gbdata, length, sp, current_mode);

        if (next_mode != current_mode) {
            switch (current_mode) {
                case 0:







>
>
>
>
>
>
>
>
>
>
>







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
    current_mode = 0;
    last_mode = 0;
    number_pad_posn = 0;

    if (reader) {
        strcat(binary, "1010"); /* FNC3 - Reader Initialisation */
    }
    
    if (eci != 3) {
        strcat(binary, "11000"); /* ECI */
        for (q = 0; q < 10; q++) {
            if (eci & (0x100 >> q)) {
                strcat(binary, "1");
            } else {
                strcat(binary, "0");
            }
        }
    }

    do {
        next_mode = seek_forward(gbdata, length, sp, current_mode);

        if (next_mode != current_mode) {
            switch (current_mode) {
                case 0:
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
    int* gbdata = (int *) _alloca((length + 1) * sizeof (int));
#endif

    for (i = 0; i < 1460; i++) {
        word[i] = 0;
    }

    switch (symbol->input_mode) {
        case DATA_MODE:
            for (i = 0; i < length; i++) {
                gbdata[i] = (int) source[i];
            }
            break;
        default:
            /* Convert Unicode input to GB-2312 */
            error_number = utf8toutf16(symbol, source, utfdata, &length);
            if (error_number != 0) {
                return error_number;
            }

            for (i = 0; i < length; i++) {
                if (utfdata[i] <= 0xff) {
                    gbdata[i] = utfdata[i];
                } else {
                    j = 0;
                    glyph = 0;
                    do {
                        if (gb2312_lookup[j * 2] == utfdata[i]) {
                            glyph = gb2312_lookup[(j * 2) + 1];
                        }
                        j++;
                    } while ((j < 7445) && (glyph == 0));
                    if (glyph == 0) {
                        strcpy(symbol->errtxt, "Invalid character in input data");
                        return ZINT_ERROR_INVALID_DATA;
                    }
                    gbdata[i] = glyph;
                }
            }
            break;
    }

    if (symbol->output_options & READER_INIT) reader = 1;

    error_number = gm_encode(gbdata, length, binary, reader);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Input data too long");
        return error_number;
    }

    /* Determine the size of the symbol */
    data_cw = strlen(binary) / 7;

    auto_layers = 13;







|
<
|
|
|
|
<
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<




|

|







1060
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
    int* gbdata = (int *) _alloca((length + 1) * sizeof (int));
#endif

    for (i = 0; i < 1460; i++) {
        word[i] = 0;
    }

    if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {

        for (i = 0; i < length; i++) {
            gbdata[i] = (int) source[i];
        }
    } else {

        /* Convert Unicode input to GB-2312 */
        error_number = utf8toutf16(symbol, source, utfdata, &length);
        if (error_number != 0) {
            return error_number;
        }

        for (i = 0; i < length; i++) {
            if (utfdata[i] <= 0xff) {
                gbdata[i] = utfdata[i];
            } else {
                j = 0;
                glyph = 0;
                do {
                    if (gb2312_lookup[j * 2] == utfdata[i]) {
                        glyph = gb2312_lookup[(j * 2) + 1];
                    }
                    j++;
                } while ((j < 7445) && (glyph == 0));
                if (glyph == 0) {
                    strcpy(symbol->errtxt, "Invalid character in input data (E30)");
                    return ZINT_ERROR_INVALID_DATA;
                }
                gbdata[i] = glyph;
            }
        }

    }

    if (symbol->output_options & READER_INIT) reader = 1;

    error_number = gm_encode(gbdata, length, binary, reader, symbol->eci);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Input data too long (E31)");
        return error_number;
    }

    /* Determine the size of the symbol */
    data_cw = strlen(binary) / 7;

    auto_layers = 13;
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
        case 4: data_max = 875;
            break;
        case 5: data_max = 729;
            break;
    }

    if (data_cw > data_max) {
        strcpy(symbol->errtxt, "Input data too long");
        return ZINT_ERROR_TOO_LONG;
    }

    gm_add_ecc(binary, data_cw, layers, ecc_level, word);
    size = 6 + (layers * 12);
    modules = 1 + (layers * 2);








|







1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
        case 4: data_max = 875;
            break;
        case 5: data_max = 729;
            break;
    }

    if (data_cw > data_max) {
        strcpy(symbol->errtxt, "Input data too long (E32)");
        return ZINT_ERROR_TOO_LONG;
    }

    gm_add_ecc(binary, data_cw, layers, ecc_level, word);
    size = 6 + (layers * 12);
    modules = 1 + (layers * 2);

Changes to jni/zint/backend/gridmtx.h.
79
80
81
82
83
84
85

86
87
88
89
90
91
92
    1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6
};

static const int gm_b2[] = {
    0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6
};


static const int gm_ebeb[] = {
    /* E1 B3 E2 B4 */
    0, 0, 0, 0, // version 1
    3, 1, 0, 0,
    5, 1, 0, 0,
    7, 1, 0, 0,
    9, 1, 0, 0,







>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6
};

static const int gm_b2[] = {
    0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6
};

/* Values from table A.1 */
static const int gm_ebeb[] = {
    /* E1 B3 E2 B4 */
    0, 0, 0, 0, // version 1
    3, 1, 0, 0,
    5, 1, 0, 0,
    7, 1, 0, 0,
    9, 1, 0, 0,
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    29, 1, 0, 0,
    39, 1, 0, 0,
    49, 1, 0, 0,
    8, 2, 0, 0, // version 4
    16, 2, 0, 0,
    24, 2, 0, 0,
    32, 2, 0, 0,
    41, 1, 10, 1,
    12, 2, 0, 0, // version 5
    24, 2, 0, 0,
    36, 2, 0, 0,
    48, 2, 0, 0,
    61, 1, 60, 1,
    11, 3, 0, 0, // version 6
    23, 1, 22, 2,







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    29, 1, 0, 0,
    39, 1, 0, 0,
    49, 1, 0, 0,
    8, 2, 0, 0, // version 4
    16, 2, 0, 0,
    24, 2, 0, 0,
    32, 2, 0, 0,
    41, 1, 40, 1,
    12, 2, 0, 0, // version 5
    24, 2, 0, 0,
    36, 2, 0, 0,
    48, 2, 0, 0,
    61, 1, 60, 1,
    11, 3, 0, 0, // version 6
    23, 1, 22, 2,
Changes to jni/zint/backend/gs1.c.
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    temp[0] = itoc(ten);
    strcat(ai_string, temp);
    temp[0] = itoc(unit);
    strcat(ai_string, temp);
    strcat(ai_string, ")");
}

int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, char reduced[]) {
    int i, j, last_ai, ai_latch;
    char ai_string[6];
    int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length;
    int ai_value[100], ai_location[100], ai_count, data_location[100], data_length[100];
    int error_latch;

    /* Detect extended ASCII characters */
    for (i = 0; i < src_len; i++) {
        if (source[i] >= 128) {
            strcpy(symbol->errtxt, "Extended ASCII characters are not supported by GS1");
            return ZINT_ERROR_INVALID_DATA;
        }
        if (source[i] < 32) {
            strcpy(symbol->errtxt, "Control characters are not supported by GS1");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    if (source[0] != '[') {
        strcpy(symbol->errtxt, "Data does not start with an AI");
        return ZINT_ERROR_INVALID_DATA;
    }

    /* Check the position of the brackets */
    bracket_level = 0;
    max_bracket_level = 0;
    ai_length = 0;







|









|



|





|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    temp[0] = itoc(ten);
    strcat(ai_string, temp);
    temp[0] = itoc(unit);
    strcat(ai_string, temp);
    strcat(ai_string, ")");
}

int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]) {
    int i, j, last_ai, ai_latch;
    char ai_string[6];
    int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length;
    int ai_value[100], ai_location[100], ai_count, data_location[100], data_length[100];
    int error_latch;

    /* Detect extended ASCII characters */
    for (i = 0; i < src_len; i++) {
        if (source[i] >= 128) {
            strcpy(symbol->errtxt, "Extended ASCII characters are not supported by GS1 (B50)");
            return ZINT_ERROR_INVALID_DATA;
        }
        if (source[i] < 32) {
            strcpy(symbol->errtxt, "Control characters are not supported by GS1 (B51)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    if (source[0] != '[') {
        strcpy(symbol->errtxt, "Data does not start with an AI (B52)");
        return ZINT_ERROR_INVALID_DATA;
    }

    /* Check the position of the brackets */
    bracket_level = 0;
    max_bracket_level = 0;
    ai_length = 0;
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
            max_ai_length = ai_length;
        }
    }
    min_ai_length--;

    if (bracket_level != 0) {
        /* Not all brackets are closed */
        strcpy(symbol->errtxt, "Malformed AI in input data (brackets don\'t match)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (max_bracket_level > 1) {
        /* Nested brackets */
        strcpy(symbol->errtxt, "Found nested brackets in input data");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (max_ai_length > 4) {
        /* AI is too long */
        strcpy(symbol->errtxt, "Invalid AI in input data (AI too long)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (min_ai_length <= 1) {
        /* AI is too short */
        strcpy(symbol->errtxt, "Invalid AI in input data (AI too short)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (ai_latch == 1) {
        /* Non-numeric data in AI */
        strcpy(symbol->errtxt, "Invalid AI in input data (non-numeric characters in AI)");
        return ZINT_ERROR_INVALID_DATA;
    }

    ai_count = 0;
    for (i = 1; i < src_len; i++) {
        if (source[i - 1] == '[') {
            ai_location[ai_count] = i;







|





|





|





|





|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
            max_ai_length = ai_length;
        }
    }
    min_ai_length--;

    if (bracket_level != 0) {
        /* Not all brackets are closed */
        strcpy(symbol->errtxt, "Malformed AI in input data (brackets don\'t match) (B53)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (max_bracket_level > 1) {
        /* Nested brackets */
        strcpy(symbol->errtxt, "Found nested brackets in input data (B54)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (max_ai_length > 4) {
        /* AI is too long */
        strcpy(symbol->errtxt, "Invalid AI in input data (AI too long) (B55)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (min_ai_length <= 1) {
        /* AI is too short */
        strcpy(symbol->errtxt, "Invalid AI in input data (AI too short) (B56)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if (ai_latch == 1) {
        /* Non-numeric data in AI */
        strcpy(symbol->errtxt, "Invalid AI in input data (non-numeric characters in AI) (B57)");
        return ZINT_ERROR_INVALID_DATA;
    }

    ai_count = 0;
    for (i = 1; i < src_len; i++) {
        if (source[i - 1] == '[') {
            ai_location[ai_count] = i;
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        } while ((source[data_location[i] + data_length[i] - 1] != '[') && (data_location[i] + data_length[i] <= src_len));
        data_length[i]--;
    }

    for (i = 0; i < ai_count; i++) {
        if (data_length[i] == 0) {
            /* No data for given AI */
            strcpy(symbol->errtxt, "Empty data field in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    error_latch = 0;
    strcpy(ai_string, "");
    for (i = 0; i < ai_count; i++) {







|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        } while ((source[data_location[i] + data_length[i] - 1] != '[') && (data_location[i] + data_length[i] <= src_len));
        data_length[i]--;
    }

    for (i = 0; i < ai_count; i++) {
        if (data_length[i] == 0) {
            /* No data for given AI */
            strcpy(symbol->errtxt, "Empty data field in input data (B58)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    error_latch = 0;
    strcpy(ai_string, "");
    for (i = 0; i < ai_count; i++) {
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
            /* error has just been detected: capture AI */
            itostr(ai_string, ai_value[i]);
            error_latch += 4;
        }
    }

    if (error_latch == 5) {
        strcpy(symbol->errtxt, "Invalid data length for AI ");
        strcat(symbol->errtxt, ai_string);
        return ZINT_ERROR_INVALID_DATA;
    }

    if (error_latch == 6) {
        strcpy(symbol->errtxt, "Invalid AI value ");
        strcat(symbol->errtxt, ai_string);
        return ZINT_ERROR_INVALID_DATA;
    }

    /* Resolve AI data - put resulting string in 'reduced' */
    j = 0;
    last_ai = 0;







|





|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
            /* error has just been detected: capture AI */
            itostr(ai_string, ai_value[i]);
            error_latch += 4;
        }
    }

    if (error_latch == 5) {
        strcpy(symbol->errtxt, "Invalid data length for AI (B59)");
        strcat(symbol->errtxt, ai_string);
        return ZINT_ERROR_INVALID_DATA;
    }

    if (error_latch == 6) {
        strcpy(symbol->errtxt, "Invalid AI value (B60)");
        strcat(symbol->errtxt, ai_string);
        return ZINT_ERROR_INVALID_DATA;
    }

    /* Resolve AI data - put resulting string in 'reduced' */
    j = 0;
    last_ai = 0;
349
350
351
352
353
354
355
356
357
358
        return error_number;
    }

    if (strlen(temp) < src_len + 5) {
        ustrcpy(reduced, (unsigned char*) temp);
        return 0;
    }
    strcpy(symbol->errtxt, "ugs1_verify overflow");
    return ZINT_ERROR_INVALID_DATA;
}







|


349
350
351
352
353
354
355
356
357
358
        return error_number;
    }

    if (strlen(temp) < src_len + 5) {
        ustrcpy(reduced, (unsigned char*) temp);
        return 0;
    }
    strcpy(symbol->errtxt, "ugs1_verify overflow (B61)");
    return ZINT_ERROR_INVALID_DATA;
}
Changes to jni/zint/backend/gs1.h.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#ifndef __GS1_H
#define __GS1_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, char reduced[]);
    extern int ugs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, unsigned char reduced[]);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __GS1_H */







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#ifndef __GS1_H
#define __GS1_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]);
    extern int ugs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, unsigned char reduced[]);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __GS1_H */
Added jni/zint/backend/hanxin.c.










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
/*  hanxin.c - Han Xin Code

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
 */

/* This code attempts to implement Han Xin Code according to AIMD-015:2010 (Rev 0.8) */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "common.h"
#include "reedsol.h"
#include "hanxin.h"
#include "gb18030.h"
#include "assert.h"

/* Find which submode to use for a text character */
int getsubmode(char input) {
    int submode = 2;

    if ((input >= '0') && (input <= '9')) {
        submode = 1;
    }

    if ((input >= 'A') && (input <= 'Z')) {
        submode = 1;
    }

    if ((input >= 'a') && (input <= 'z')) {
        submode = 1;
    }

    return submode;
}

/* Calculate the approximate length of the binary string */
int calculate_binlength(char mode[], int source[], int length, int eci) {
    int i;
    char lastmode = 't';
    int est_binlen = 0;
    int submode = 1;

    if (eci != 3) {
        est_binlen += 12;
    }

    i = 0;
    do {
        switch (mode[i]) {
            case 'n':
                if (lastmode != 'n') {
                    est_binlen += 14;
                    lastmode = 'n';
                }
                est_binlen += 4;
                break;
            case 't':
                if (lastmode != 't') {
                    est_binlen += 10;
                    lastmode = 't';
                    submode = 1;
                }
                if (getsubmode((char) source[i]) != submode) {
                    est_binlen += 6;
                    submode = getsubmode((char) source[i]);
                }
                est_binlen += 6;
                break;
            case 'b':
                if (lastmode != 'b') {
                    est_binlen += 17;
                    lastmode = 'b';
                }
                est_binlen += 8;
                break;
            case '1':
                if (lastmode != '1') {
                    est_binlen += 16;
                    lastmode = '1';
                }
                est_binlen += 12;
                break;
            case '2':
                if (lastmode != '2') {
                    est_binlen += 16;
                    lastmode = '2';
                }
                est_binlen += 12;
                break;
            case 'd':
                if (lastmode != 'd') {
                    est_binlen += 16;
                    lastmode = 'd';
                }
                est_binlen += 15;
                break;
            case 'f':
                if (lastmode != 'f') {
                    est_binlen += 4;
                    lastmode = 'f';
                }
                est_binlen += 21;
                i++;
                break;
        }
        i++;
    } while (i < length);

    return est_binlen;
}

int isRegion1(int glyph) {
    int first_byte, second_byte;
    int valid = 0;

    first_byte = (glyph & 0xff00) >> 8;
    second_byte = glyph & 0xff;

    if ((first_byte >= 0xb0) && (first_byte <= 0xd7)) {
        if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
            valid = 1;
        }
    }

    if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) {
        if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
            valid = 1;
        }
    }

    if ((glyph >= 0xa8a1) && (glyph <= 0xa8c0)) {
        valid = 1;
    }

    return valid;
}

int isRegion2(int glyph) {
    int first_byte, second_byte;
    int valid = 0;

    first_byte = (glyph & 0xff00) >> 8;
    second_byte = glyph & 0xff;

    if ((first_byte >= 0xd8) && (first_byte <= 0xf7)) {
        if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
            valid = 1;
        }
    }

    return valid;
}

int isDoubleByte(int glyph) {
    int first_byte, second_byte;
    int valid = 0;

    first_byte = (glyph & 0xff00) >> 8;
    second_byte = glyph & 0xff;

    if ((first_byte >= 0x81) && (first_byte <= 0xfe)) {
        if ((second_byte >= 0x40) && (second_byte <= 0x7e)) {
            valid = 1;
        }

        if ((second_byte >= 0x80) && (second_byte <= 0xfe)) {
            valid = 1;
        }
    }

    return valid;
}

int isFourByte(int glyph, int glyph2) {
    int first_byte, second_byte;
    int third_byte, fourth_byte;
    int valid = 0;

    first_byte = (glyph & 0xff00) >> 8;
    second_byte = glyph & 0xff;
    third_byte = (glyph2 & 0xff00) >> 8;
    fourth_byte = glyph2 & 0xff;

    if ((first_byte >= 0x81) && (first_byte <= 0xfe)) {
        if ((second_byte >= 0x30) && (second_byte <= 0x39)) {
            if ((third_byte >= 0x81) && (third_byte <= 0xfe)) {
                if ((fourth_byte >= 0x30) && (fourth_byte <= 0x39)) {
                    valid = 1;
                }
            }
        }
    }

    return valid;
}

/* Calculate mode switching */
void hx_define_mode(char mode[], int source[], int length) {
    int i;
    char lastmode = 't';
    int done;

    i = 0;
    do {
        done = 0;

        if (isRegion1(source[i])) {
            mode[i] = '1';
            done = 1;
            i++;
        }

        if ((done == 0) && (isRegion2(source[i]))) {
            mode[i] = '2';
            done = 1;
            i++;
        }

        if ((done == 0) && (isDoubleByte(source[i]))) {
            mode[i] = 'd';
            done = 1;
            i++;
        }

        if ((done == 0) && (i < length - 1)) {
            if (isFourByte(source[i], source[i + 1])) {
                mode[i] = 'f';
                mode[i + 1] = 'f';
                done = 1;
                i += 2;
            }
        }

        if (done == 0) {
            if ((source[i] >= '0') && (source[i] <= '9')) {
                mode[i] = 'n';
                if (lastmode != 'n') {
                    lastmode = 'n';
                }
            } else {
                if ((source[i] <= 127) && ((source[i] <= 27) || (source[i] >= 32))) {
                    mode[i] = 't';
                    if (lastmode != 't') {
                        lastmode = 't';
                    }
                } else {
                    mode[i] = 'b';
                    if (lastmode != 'b') {
                        lastmode = 'b';
                    }
                }
            }
            i++;
        }
    } while (i < length);
    mode[length] = '\0';
}

/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */
int lookup_text1(char input) {
    int encoding_value = 0;

    if ((input >= '0') && (input <= '9')) {
        encoding_value = input - '0';
    }

    if ((input >= 'A') && (input <= 'Z')) {
        encoding_value = input - 'A' + 10;
    }

    if ((input >= 'a') && (input <= 'z')) {
        encoding_value = input - 'a' + 36;
    }

    return encoding_value;
}

/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */
int lookup_text2(char input) {
    int encoding_value = 0;

    if ((input >= 0) && (input <= 27)) {
        encoding_value = input;
    }

    if ((input >= ' ') && (input <= '/')) {
        encoding_value = input - ' ' + 28;
    }

    if ((input >= '[') && (input <= 96)) {
        encoding_value = input - '[' + 51;
    }

    if ((input >= '{') && (input <= 127)) {
        encoding_value = input - '{' + 57;
    }

    return encoding_value;
}

/* Convert input data to binary stream */
void calculate_binary(char binary[], char mode[], int source[], int length, int eci) {
    int block_length;
    int position = 0;
    int i, p, count, encoding_value;
    int debug = 0;
    int first_byte, second_byte;
    int third_byte, fourth_byte;
    int glyph;
    int submode;

    if (eci != 3) {
        strcat(binary, "1000"); // ECI
        for (p = 0; p < 8; p++) {
            if (eci & (0x80 >> p)) {
                strcat(binary, "1");
            } else {
                strcat(binary, "0");
            }
        }
    }

    do {
        block_length = 0;
        do {
            block_length++;
        } while (mode[position + block_length] == mode[position]);

        switch (mode[position]) {
            case 'n':
                /* Numeric mode */
                /* Mode indicator */
                strcat(binary, "0001");

                if (debug) {
                    printf("Numeric\n");
                }

                i = 0;

                while (i < block_length) {
                    int first = 0, second = 0, third = 0;

                    first = posn(NEON, (char) source[position + i]);
                    count = 1;
                    encoding_value = first;

                    if (i + 1 < block_length && mode[position + i + 1] == 'n') {
                        second = posn(NEON, (char) source[position + i + 1]);
                        count = 2;
                        encoding_value = (encoding_value * 10) + second;

                        if (i + 2 < block_length && mode[position + i + 2] == 'n') {
                            third = posn(NEON, (char) source[position + i + 2]);
                            count = 3;
                            encoding_value = (encoding_value * 10) + third;
                        }
                    }

                    for (p = 0; p < 10; p++) {
                        if (encoding_value & (0x200 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    if (debug) {
                        printf("0x%4x (%d)", encoding_value, encoding_value);
                    }

                    i += count;
                }

                /* Mode terminator depends on number of characters in last group (Table 2) */
                switch (count) {
                    case 1:
                        strcat(binary, "1111111101");
                        break;
                    case 2:
                        strcat(binary, "1111111110");
                        break;
                    case 3:
                        strcat(binary, "1111111111");
                        break;
                }

                if (debug) {
                    printf(" (TERM %d)\n", count);
                }

                break;
            case 't':
                /* Text mode */
                if (position != 0) {
                    /* Mode indicator */
                    strcat(binary, "0010");

                    if (debug) {
                        printf("Text\n");
                    }
                }

                submode = 1;

                i = 0;

                while (i < block_length) {

                    if (getsubmode((char) source[i + position]) != submode) {
                        /* Change submode */
                        strcat(binary, "111110");
                        submode = getsubmode((char) source[i + position]);
                        if (debug) {
                            printf("SWITCH ");
                        }
                    }

                    if (submode == 1) {
                        encoding_value = lookup_text1((char) source[i + position]);
                    } else {
                        encoding_value = lookup_text2((char) source[i + position]);
                    }

                    for (p = 0; p < 6; p++) {
                        if (encoding_value & (0x20 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    if (debug) {
                        printf("%c (%d) ", (char) source[i], encoding_value);
                    }
                    i++;
                }

                /* Terminator */
                strcat(binary, "111111");

                if (debug) {
                    printf("\n");
                }
                break;
            case 'b':
                /* Binary Mode */
                /* Mode indicator */
                strcat(binary, "0011");

                /* Count indicator */
                for (p = 0; p < 13; p++) {
                    if (block_length & (0x1000 >> p)) {
                        strcat(binary, "1");
                    } else {
                        strcat(binary, "0");
                    }
                }

                if (debug) {
                    printf("Binary (length %d)\n", block_length);
                }

                i = 0;

                while (i < block_length) {

                    /* 8-bit bytes with no conversion */
                    for (p = 0; p < 8; p++) {
                        if (source[i + position] & (0x80 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    if (debug) {
                        printf("%d ", source[i + position]);
                    }

                    i++;
                }

                if (debug) {
                    printf("\n");
                }
                break;
            case '1':
                /* Region 1 encoding */
                /* Mode indicator */
                strcat(binary, "0100");

                if (debug) {
                    printf("Region 1\n");
                }

                i = 0;

                while (i < block_length) {
                    first_byte = (source[i + position] & 0xff00) >> 8;
                    second_byte = source[i + position] & 0xff;

                    /* Subset 1 */
                    glyph = (0x5e * (first_byte - 0xb0)) + (second_byte - 0xa1);

                    /* Subset 2 */
                    if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) {
                        if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
                            glyph = (0x5e * first_byte - 0xa1) + (second_byte - 0xa1) + 0xeb0;
                        }
                    }

                    /* Subset 3 */
                    if ((source[i + position] >= 0xa8a1) && (source[i + position] <= 0xa8c0)) {
                        glyph = (second_byte - 0xa1) + 0xfca;
                    }

                    if (debug) {
                        printf("%d ", glyph);
                    }

                    for (p = 0; p < 12; p++) {
                        if (glyph & (0x800 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    i++;
                }

                /* Terminator */
                strcat(binary, "111111111111");

                if (debug) {
                    printf("\n");
                }

                break;
            case '2':
                /* Region 2 encoding */
                /* Mode indicator */
                strcat(binary, "0101");

                if (debug) {
                    printf("Region 2\n");
                }

                i = 0;

                while (i < block_length) {
                    first_byte = (source[i + position] & 0xff00) >> 8;
                    second_byte = source[i + position] & 0xff;

                    glyph = (0x5e * (first_byte - 0xd8)) + (second_byte - 0xa1);

                    if (debug) {
                        printf("%d ", glyph);
                    }

                    for (p = 0; p < 12; p++) {
                        if (glyph & (0x800 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    i++;
                }

                /* Terminator */
                strcat(binary, "111111111111");

                if (debug) {
                    printf("\n");
                }
                break;
            case 'd':
                /* Double byte encoding */
                /* Mode indicator */
                strcat(binary, "0110");

                if (debug) {
                    printf("Double byte\n");
                }

                i = 0;

                while (i < block_length) {
                    first_byte = (source[i + position] & 0xff00) >> 8;
                    second_byte = source[i + position] & 0xff;

                    if (second_byte <= 0x7e) {
                        glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x40);
                    } else {
                        glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x41);
                    }

                    if (debug) {
                        printf("%d ", glyph);
                    }

                    for (p = 0; p < 15; p++) {
                        if (glyph & (0x4000 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    i++;
                }

                /* Terminator */
                strcat(binary, "111111111111111");
                /* Terminator sequence of length 12 is a mistake
                   - confirmed by Wang Yi */

                if (debug) {
                    printf("\n");
                }
                break;
            case 'f':
                /* Four-byte encoding */
                if (debug) {
                    printf("Four byte\n");
                }

                i = 0;

                while (i < block_length) {

                    /* Mode indicator */
                    strcat(binary, "0111");

                    first_byte = (source[i + position] & 0xff00) >> 8;
                    second_byte = source[i + position] & 0xff;
                    third_byte = (source[i + position + 1] & 0xff00) >> 8;
                    fourth_byte = source[i + position + 1] & 0xff;

                    glyph = (0x3138 * (first_byte - 0x81)) + (0x04ec * (second_byte - 0x30)) +
                            (0x0a * (third_byte - 0x81)) + (fourth_byte - 0x30);

                    if (debug) {
                        printf("%d ", glyph);
                    }

                    for (p = 0; p < 15; p++) {
                        if (glyph & (0x4000 >> p)) {
                            strcat(binary, "1");
                        } else {
                            strcat(binary, "0");
                        }
                    }

                    i += 2;
                }

                /* No terminator */

                if (debug) {
                    printf("\n");
                }
                break;

        }

        position += block_length;

    } while (position < length);
}

/* Finder pattern for top left of symbol */
void hx_place_finder_top_left(unsigned char* grid, int size) {
    int xp, yp;
    int x = 0, y = 0;

    int finder[] = {
        1, 1, 1, 1, 1, 1, 1,
        1, 0, 0, 0, 0, 0, 0,
        1, 0, 1, 1, 1, 1, 1,
        1, 0, 1, 0, 0, 0, 0,
        1, 0, 1, 0, 1, 1, 1,
        1, 0, 1, 0, 1, 1, 1,
        1, 0, 1, 0, 1, 1, 1
    };

    for (xp = 0; xp < 7; xp++) {
        for (yp = 0; yp < 7; yp++) {
            if (finder[xp + (7 * yp)] == 1) {
                grid[((yp + y) * size) + (xp + x)] = 0x11;
            } else {
                grid[((yp + y) * size) + (xp + x)] = 0x10;
            }
        }
    }
}

/* Finder pattern for top right and bottom left of symbol */
void hx_place_finder(unsigned char* grid, int size, int x, int y) {
    int xp, yp;

    int finder[] = {
        1, 1, 1, 1, 1, 1, 1,
        0, 0, 0, 0, 0, 0, 1,
        1, 1, 1, 1, 1, 0, 1,
        0, 0, 0, 0, 1, 0, 1,
        1, 1, 1, 0, 1, 0, 1,
        1, 1, 1, 0, 1, 0, 1,
        1, 1, 1, 0, 1, 0, 1
    };

    for (xp = 0; xp < 7; xp++) {
        for (yp = 0; yp < 7; yp++) {
            if (finder[xp + (7 * yp)] == 1) {
                grid[((yp + y) * size) + (xp + x)] = 0x11;
            } else {
                grid[((yp + y) * size) + (xp + x)] = 0x10;
            }
        }
    }
}

/* Finder pattern for bottom right of symbol */
void hx_place_finder_bottom_right(unsigned char* grid, int size) {
    int xp, yp;
    int x = size - 7, y = size - 7;

    int finder[] = {
        1, 1, 1, 0, 1, 0, 1,
        1, 1, 1, 0, 1, 0, 1,
        1, 1, 1, 0, 1, 0, 1,
        0, 0, 0, 0, 1, 0, 1,
        1, 1, 1, 1, 1, 0, 1,
        0, 0, 0, 0, 0, 0, 1,
        1, 1, 1, 1, 1, 1, 1
    };

    for (xp = 0; xp < 7; xp++) {
        for (yp = 0; yp < 7; yp++) {
            if (finder[xp + (7 * yp)] == 1) {
                grid[((yp + y) * size) + (xp + x)] = 0x11;
            } else {
                grid[((yp + y) * size) + (xp + x)] = 0x10;
            }
        }
    }
}

/* Avoid plotting outside symbol or over finder patterns */
void hx_safe_plot(unsigned char *grid, int size, int x, int y, int value) {
    if ((x >= 0) && (x < size)) {
        if ((y >= 0) && (y < size)) {
            if (grid[(y * size) + x] == 0) {
                grid[(y * size) + x] = value;
            }
        }
    }
}

/* Plot an alignment pattern around top and right of a module */
void hx_plot_alignment(unsigned char *grid, int size, int x, int y, int w, int h) {
    int i;
    hx_safe_plot(grid, size, x, y, 0x11);
    hx_safe_plot(grid, size, x - 1, y + 1, 0x10);

    for (i = 1; i <= w; i++) {
        /* Top */
        hx_safe_plot(grid, size, x - i, y, 0x11);
        hx_safe_plot(grid, size, x - i - 1, y + 1, 0x10);
    }

    for (i = 1; i < h; i++) {
        /* Right */
        hx_safe_plot(grid, size, x, y + i, 0x11);
        hx_safe_plot(grid, size, x - 1, y + i + 1, 0x10);
    }
}

/* Plot assistant alignment patterns */
void hx_plot_assistant(unsigned char *grid, int size, int x, int y) {
    hx_safe_plot(grid, size, x - 1, y - 1, 0x10);
    hx_safe_plot(grid, size, x, y - 1, 0x10);
    hx_safe_plot(grid, size, x + 1, y - 1, 0x10);
    hx_safe_plot(grid, size, x - 1, y, 0x10);
    hx_safe_plot(grid, size, x, y, 0x11);
    hx_safe_plot(grid, size, x + 1, y, 0x10);
    hx_safe_plot(grid, size, x - 1, y + 1, 0x10);
    hx_safe_plot(grid, size, x, y + 1, 0x10);
    hx_safe_plot(grid, size, x + 1, y + 1, 0x10);
}

/* Put static elements in the grid */
void hx_setup_grid(unsigned char* grid, int size, int version) {
    int i, j;

    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            grid[(i * size) + j] = 0;
        }
    }

    /* Add finder patterns */
    hx_place_finder_top_left(grid, size);
    hx_place_finder(grid, size, 0, size - 7);
    hx_place_finder(grid, size, size - 7, 0);
    hx_place_finder_bottom_right(grid, size);

    /* Add finder pattern separator region */
    for (i = 0; i < 8; i++) {
        /* Top left */
        grid[(7 * size) + i] = 0x10;
        grid[(i * size) + 7] = 0x10;

        /* Top right */
        grid[(7 * size) + (size - i - 1)] = 0x10;
        grid[((size - i - 1) * size) + 7] = 0x10;

        /* Bottom left */
        grid[(i * size) + (size - 8)] = 0x10;
        grid[((size - 8) * size) + i] = 0x10;

        /* Bottom right */
        grid[((size - 8) * size) + (size - i - 1)] = 0x10;
        grid[((size - i - 1) * size) + (size - 8)] = 0x10;
    }

    /* Reserve function information region */
    for (i = 0; i < 9; i++) {
        /* Top left */
        grid[(8 * size) + i] = 0x10;
        grid[(i * size) + 8] = 0x10;

        /* Top right */
        grid[(8 * size) + (size - i - 1)] = 0x10;
        grid[((size - i - 1) * size) + 8] = 0x10;

        /* Bottom left */
        grid[(i * size) + (size - 9)] = 0x10;
        grid[((size - 9) * size) + i] = 0x10;

        /* Bottom right */
        grid[((size - 9) * size) + (size - i - 1)] = 0x10;
        grid[((size - i - 1) * size) + (size - 9)] = 0x10;
    }

    if (version > 3) {
        int k = hx_module_k[version - 1];
        int r = hx_module_r[version - 1];
        int m = hx_module_m[version - 1];
        int x, y, row_switch, column_switch;
        int module_height, module_width;
        int mod_x, mod_y;

        /* Add assistant alignment patterns to left and right */
        y = 0;
        mod_y = 0;
        do {
            if (mod_y < m) {
                module_height = k;
            } else {
                module_height = r - 1;
            }

            if ((mod_y % 2) == 0) {
                if ((m % 2) == 1) {
                    hx_plot_assistant(grid, size, 0, y);
                }
            } else {
                if ((m % 2) == 0) {
                    hx_plot_assistant(grid, size, 0, y);
                }
                hx_plot_assistant(grid, size, size - 1, y);
            }

            mod_y++;
            y += module_height;
        } while (y < size);

        /* Add assistant alignment patterns to top and bottom */
        x = (size - 1);
        mod_x = 0;
        do {
            if (mod_x < m) {
                module_width = k;
            } else {
                module_width = r - 1;
            }

            if ((mod_x % 2) == 0) {
                if ((m % 2) == 1) {
                    hx_plot_assistant(grid, size, x, (size - 1));
                }
            } else {
                if ((m % 2) == 0) {
                    hx_plot_assistant(grid, size, x, (size - 1));
                }
                hx_plot_assistant(grid, size, x, 0);
            }

            mod_x++;
            x -= module_width;
        } while (x >= 0);

        /* Add alignment pattern */
        column_switch = 1;
        y = 0;
        mod_y = 0;
        do {
            if (mod_y < m) {
                module_height = k;
            } else {
                module_height = r - 1;
            }

            if (column_switch == 1) {
                row_switch = 1;
                column_switch = 0;
            } else {
                row_switch = 0;
                column_switch = 1;
            }

            x = (size - 1);
            mod_x = 0;
            do {
                if (mod_x < m) {
                    module_width = k;
                } else {
                    module_width = r - 1;
                }

                if (row_switch == 1) {
                    if (!(y == 0 && x == (size - 1))) {
                        hx_plot_alignment(grid, size, x, y, module_width, module_height);
                    }
                    row_switch = 0;
                } else {
                    row_switch = 1;
                }
                mod_x++;
                x -= module_width;
            } while (x >= 0);

            mod_y++;
            y += module_height;
        } while (y < size);
    }
}

/* Calculate error correction codes */
void hx_add_ecc(unsigned char fullstream[], unsigned char datastream[], int version, int ecc_level) {
    unsigned char data_block[180];
    unsigned char ecc_block[36];
    int i, j, block;
    int batch_size, data_length, ecc_length;
    int input_position = -1;
    int output_position = -1;

    for (i = 0; i < 3; i++) {
        batch_size = hx_table_d1[(((version - 1) + (ecc_level - 1)) * 9) + (3 * i)];
        data_length = hx_table_d1[(((version - 1) + (ecc_level - 1)) * 9) + (3 * i) + 1];
        ecc_length = hx_table_d1[(((version - 1) + (ecc_level - 1)) * 9) + (3 * i) + 2];

        for (block = 0; block < batch_size; block++) {
            for (j = 0; j < data_length; j++) {
                input_position++;
                output_position++;
                data_block[j] = datastream[input_position];
                fullstream[output_position] = datastream[input_position];
            }

            rs_init_gf(0x163); // x^8 + x^6 + x^5 + x + 1 = 0
            rs_init_code(ecc_length, 1);
            rs_encode(data_length, data_block, ecc_block);
            rs_free();

            for (j = 0; j < ecc_length; j++) {
                output_position++;
                fullstream[output_position] = ecc_block[ecc_length - j - 1];
            }
        }
    }
}

/* Rearrange data in batches of 13 codewords (section 5.8.2) */
void make_picket_fence(unsigned char fullstream[], unsigned char picket_fence[], int streamsize) {
    int i, start;
    int output_position = 0;

    for (start = 0; start < 13; start++) {
        for (i = start; i < streamsize; i += 13) {
            if (i < streamsize) {
                picket_fence[output_position] = fullstream[i];
                output_position++;
            }
        }
    }
}

/* Evaluate a bitmask according to table 9 */
int hx_evaluate(unsigned char *eval, int size, int pattern) {
    int x, y, block, weight;
    int result = 0;
    char state;
    int p;
    int a, b, afterCount, beforeCount;
#ifndef _MSC_VER
    char local[size * size];
#else
    char* local = (char *) _alloca((size * size) * sizeof (char));
#endif

    /* all four bitmask variants have been encoded in the 4 bits of the bytes
     * that make up the grid array. select them for evaluation according to the
     * desired pattern.*/
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            if ((eval[(y * size) + x] & (0x01 << pattern)) != 0) {
                local[(y * size) + x] = '1';
            } else {
                local[(y * size) + x] = '0';
            }
        }
    }

    /* Test 1: 1:1:1:1:3  or 3:1:1:1:1 ratio pattern in row/column */
    /* Vertical */
    for (x = 0; x < size; x++) {
        for (y = 0; y < (size - 7); y++) {
            p = 0;
            for (weight = 0; weight < 7; weight++) {
                if (local[((y + weight) * size) + x] == '1') {
                    p += (0x40 >> weight);
                }
            }
            if ((p == 0x57) || (p = 0x75)) {
                /* Pattern found, check before and after */
                beforeCount = 0;
                for (b = (y - 3); b < y; b++) {
                    if (b < 0) {
                        beforeCount++;
                    } else {
                        if (local[(b * size) + x] == '0') {
                            beforeCount++;
                        } else {
                            beforeCount = 0;
                        }
                    }
                }

                afterCount = 0;
                for (a = (y + 7); a <= (y + 9); a++) {
                    if (a >= size) {
                        afterCount++;
                    } else {
                        if (local[(a * size) + x] == '0') {
                            afterCount++;
                        } else {
                            afterCount = 0;
                        }
                    }
                }

                if ((beforeCount == 3) || (afterCount == 3)) {
                    /* Pattern is preceeded or followed by light area
                       3 modules wide */
                    result += 50;
                }
            }
        }
    }

    /* Horizontal */
    for (y = 0; y < size; y++) {
        for (x = 0; x < (size - 7); x++) {
            p = 0;
            for (weight = 0; weight < 7; weight++) {
                if (local[(y * size) + x + weight] == '1') {
                    p += (0x40 >> weight);
                }
            }
            if ((p == 0x57) || (p = 0x75)) {
                /* Pattern found, check before and after */
                beforeCount = 0;
                for (b = (x - 3); b < x; b++) {
                    if (b < 0) {
                        beforeCount++;
                    } else {
                        if (local[(y * size) + b] == '0') {
                            beforeCount++;
                        } else {
                            beforeCount = 0;
                        }
                    }
                }

                afterCount = 0;
                for (a = (x + 7); a <= (x + 9); a++) {
                    if (a >= size) {
                        afterCount++;
                    } else {
                        if (local[(y * size) + a] == '0') {
                            afterCount++;
                        } else {
                            afterCount = 0;
                        }
                    }
                }

                if ((beforeCount == 3) || (afterCount == 3)) {
                    /* Pattern is preceeded or followed by light area
                       3 modules wide */
                    result += 50;
                }
            }
        }
    }

    /* Test 2: Adjacent modules in row/column in same colour */
    /* In AIMD-15 section 5.8.3.2 it is stated... “In Table 9 below, i refers to the row
     * position of the module.” - however i being the length of the run of the
     * same colour (i.e. "block" below) in the same fashion as ISO/IEC 18004
     * makes more sense. -- Confirmed by Wang Yi */

    /* Vertical */
    for (x = 0; x < size; x++) {
        state = local[x];
        block = 0;
        for (y = 0; y < size; y++) {
            if (local[(y * size) + x] == state) {
                block++;
            } else {
                if (block > 3) {
                    result += (3 + block) * 4;
                }
                block = 0;
                state = local[(y * size) + x];
            }
        }
        if (block > 3) {
            result += (3 + block) * 4;
        }
    }

    /* Horizontal */
    for (y = 0; y < size; y++) {
        state = local[y * size];
        block = 0;
        for (x = 0; x < size; x++) {
            if (local[(y * size) + x] == state) {
                block++;
            } else {
                if (block > 3) {
                    result += (3 + block) * 4;
                }
                block = 0;
                state = local[(y * size) + x];
            }
        }
        if (block > 3) {
            result += (3 + block) * 4;
        }
    }

    return result;
}

/* Apply the four possible bitmasks for evaluation */
int hx_apply_bitmask(unsigned char *grid, int size) {
    int x, y;
    int i, j;
    int pattern, penalty[4];
    int best_pattern, best_val;
    int bit;
    unsigned char p;

#ifndef _MSC_VER
    unsigned char mask[size * size];
    unsigned char eval[size * size];
#else
    unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
    unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
#endif

    /* Perform data masking */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            mask[(y * size) + x] = 0x00;
            j = x + 1;
            i = y + 1;

            if (!(grid[(y * size) + x] & 0xf0)) {
                if ((i + j) % 2 == 0) {
                    mask[(y * size) + x] += 0x02;
                }
                if ((((i + j) % 3) + (j % 3)) % 2 == 0) {
                    mask[(y * size) + x] += 0x04;
                }
                if (((i % j) + (j % i) + (i % 3) + (j % 3)) % 2 == 0) {
                    mask[(y * size) + x] += 0x08;
                }
            }
        }
    }

    // apply data masks to grid, result in eval
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            if (grid[(y * size) + x] & 0x01) {
                p = 0xff;
            } else {
                p = 0x00;
            }

            eval[(y * size) + x] = mask[(y * size) + x] ^ p;
        }
    }

    /* Evaluate result */
    for (pattern = 0; pattern < 4; pattern++) {
        penalty[pattern] = hx_evaluate(eval, size, pattern);
    }

    best_pattern = 0;
    best_val = penalty[0];
    for (pattern = 1; pattern < 4; pattern++) {
        if (penalty[pattern] < best_val) {
            best_pattern = pattern;
            best_val = penalty[pattern];
        }
    }

    /* Apply mask */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            bit = 0;
            switch (best_pattern) {
                case 0: if (mask[(y * size) + x] & 0x01) {
                        bit = 1;
                    }
                    break;
                case 1: if (mask[(y * size) + x] & 0x02) {
                        bit = 1;
                    }
                    break;
                case 2: if (mask[(y * size) + x] & 0x04) {
                        bit = 1;
                    }
                    break;
                case 3: if (mask[(y * size) + x] & 0x08) {
                        bit = 1;
                    }
                    break;
            }
            if (bit == 1) {
                if (grid[(y * size) + x] & 0x01) {
                    grid[(y * size) + x] = 0x00;
                } else {
                    grid[(y * size) + x] = 0x01;
                }
            }
        }
    }

    return best_pattern;
}

/* Han Xin Code - main */
int han_xin(struct zint_symbol *symbol, const unsigned char source[], int length) {
    int est_binlen;
    int ecc_level = symbol->option_1;
    int i, j, version, posn = 0, glyph, glyph2;
    int data_codewords = 0, size;
    int est_codewords;
    int bitmask;
    int error_number;
    char function_information[36];
    unsigned char fi_cw[3] = {0, 0, 0};
    unsigned char fi_ecc[4];

#ifndef _MSC_VER
    int utfdata[length + 1];
    int gbdata[(length + 1) * 2];
    char mode[length + 1];
#else
    int* utfdata = (int *) _alloca((length + 1) * sizeof (int));
    int* gbdata = (int *) _alloca(((length + 1) * 2) * sizeof (int));
    char* mode = (char *) _alloca((length + 1) * sizeof (char));
    char* binary;
    unsigned char *datastream;
    unsigned char *fullstream;
    unsigned char *picket_fence;
    unsigned char *grid;
#endif

    if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {
        for (i = 0; i < length; i++) {
            gbdata[i] = (int) source[i];
        }
    } else {
        /* Convert Unicode input to GB-18030 */
        error_number = utf8toutf16(symbol, source, utfdata, &length);
        if (error_number != 0) {
            return error_number;
        }

        posn = 0;
        for (i = 0; i < length; i++) {
            if (utfdata[i] <= 0x7f) {
                gbdata[posn] = utfdata[i];
                posn++;
            } else {
                j = 0;
                glyph = 0;
                do {
                    if (gb18030_twobyte_lookup[j * 2] == utfdata[i]) {
                        glyph = gb18030_twobyte_lookup[(j * 2) + 1];
                    }
                    j++;
                } while ((j < 23940) && (glyph == 0));

                if (glyph == 0) {
                    j = 0;
                    glyph = 0;
                    glyph2 = 0;
                    do {
                        if (gb18030_fourbyte_lookup[j * 3] == utfdata[i]) {
                            glyph = gb18030_fourbyte_lookup[(j * 3) + 1];
                            glyph2 = gb18030_fourbyte_lookup[(j * 3) + 2];
                        }
                        j++;
                    } while ((j < 6793) && (glyph == 0));
                    if (glyph == 0) {
                        strcpy(symbol->errtxt, "Unknown character in input data (E40)");
                        return ZINT_ERROR_INVALID_DATA;
                    } else {
                        gbdata[posn] = glyph;
                        gbdata[posn + 1] = glyph2;
                        posn += 2;
                    }
                } else {
                    gbdata[posn] = glyph;
                    posn++;
                }
            }
        }
        length = posn;
    }

    hx_define_mode(mode, gbdata, length);

    est_binlen = calculate_binlength(mode, gbdata, length, symbol->eci);
    est_codewords = est_binlen / 8;
    if (est_binlen % 8 != 0) {
        est_codewords++;
    }

#ifndef _MSC_VER
    char binary[est_binlen + 1];
#else
    binary = (char *) _alloca((est_binlen + 10) * sizeof (char));
#endif
    memset(binary, 0, (est_binlen + 1) * sizeof (char));

    if ((ecc_level <= 0) || (ecc_level >= 5)) {
        ecc_level = 1;
    }

    calculate_binary(binary, mode, gbdata, length, symbol->eci);

    version = 85;
    for (i = 84; i > 0; i--) {
        switch (ecc_level) {
            case 1:
                if (hx_data_codewords_L1[i - 1] > est_codewords) {
                    version = i;
                    data_codewords = hx_data_codewords_L1[i - 1];
                }
                break;
            case 2:
                if (hx_data_codewords_L2[i - 1] > est_codewords) {
                    version = i;
                    data_codewords = hx_data_codewords_L2[i - 1];
                }
                break;
            case 3:
                if (hx_data_codewords_L3[i - 1] > est_codewords) {
                    version = i;
                    data_codewords = hx_data_codewords_L3[i - 1];
                }
                break;
            case 4:
                if (hx_data_codewords_L4[i - 1] > est_codewords) {
                    version = i;
                    data_codewords = hx_data_codewords_L4[i - 1];
                }
                break;
            default:
                assert(0);
                break;
        }
    }

    if (version == 85) {
        strcpy(symbol->errtxt, "Input too long for selected error correction level (E41)");
        return ZINT_ERROR_TOO_LONG;
    }

    if ((symbol->option_2 < 0) || (symbol->option_2 > 84)) {
        symbol->option_2 = 0;
    }

    if (symbol->option_2 > version) {
        version = symbol->option_2;
    }

    /* If there is spare capacity, increase the level of ECC */

    if ((ecc_level == 1) && (est_codewords < hx_data_codewords_L2[version - 1])) {
        ecc_level = 2;
        data_codewords = hx_data_codewords_L2[version - 1];
    }

    if ((ecc_level == 2) && (est_codewords < hx_data_codewords_L3[version - 1])) {
        ecc_level = 3;
        data_codewords = hx_data_codewords_L3[version - 1];
    }

    if ((ecc_level == 3) && (est_codewords < hx_data_codewords_L4[version - 1])) {
        ecc_level = 4;
        data_codewords = hx_data_codewords_L4[version - 1];
    }

    //printf("Version %d, ECC %d\n", version, ecc_level);

    size = (version * 2) + 21;

#ifndef _MSC_VER
    unsigned char datastream[data_codewords];
    unsigned char fullstream[hx_total_codewords[version - 1]];
    unsigned char picket_fence[hx_total_codewords[version - 1]];
    unsigned char grid[size * size];
#else
    datastream = (unsigned char *) _alloca((data_codewords) * sizeof (unsigned char));
    fullstream = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char));
    picket_fence = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char));
    grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
#endif

    for (i = 0; i < data_codewords; i++) {
        datastream[i] = 0;
    }

    for (i = 0; i < est_binlen; i++) {
        if (binary[i] == '1') {
            datastream[i / 8] += 0x80 >> (i % 8);
        }
    }

    hx_setup_grid(grid, size, version);

    hx_add_ecc(fullstream, datastream, version, ecc_level);

    make_picket_fence(fullstream, picket_fence, hx_total_codewords[version - 1]);

    /* Populate grid */
    j = 0;
    for (i = 0; i < (size * size); i++) {
        if (grid[i] == 0x00) {
            if (j < (hx_total_codewords[version - 1] * 8)) {
                if (picket_fence[(j / 8)] & (0x80 >> (j % 8))) {
                    grid[i] = 0x01;
                }
                j++;
            }
        }
    }

    bitmask = hx_apply_bitmask(grid, size);

    /* Form function information string */
    for (i = 0; i < 34; i++) {
        if (i % 2) {
            function_information[i] = '1';
        } else {
            function_information[i] = '0';
        }
    }
    function_information[34] = '\0';

    for (i = 0; i < 8; i++) {
        if ((version + 20) & (0x80 >> i)) {
            function_information[i] = '1';
        } else {
            function_information[i] = '0';
        }
    }

    for (i = 0; i < 2; i++) {
        if (ecc_level & (0x02 >> i)) {
            function_information[i + 8] = '1';
        } else {
            function_information[i + 8] = '0';
        }
    }

    for (i = 0; i < 2; i++) {
        if (bitmask & (0x02 >> i)) {
            function_information[i + 10] = '1';
        } else {
            function_information[i + 10] = '0';
        }
    }



    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            if (function_information[(i * 4) + j] == '1') {
                fi_cw[i] += (0x08 >> j);
            }
        }
    }

    rs_init_gf(0x13);
    rs_init_code(4, 1);
    rs_encode(3, fi_cw, fi_ecc);
    rs_free();

    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            if (fi_ecc[3 - i] & (0x08 >> j)) {
                function_information[(i * 4) + j + 12] = '1';
            } else {
                function_information[(i * 4) + j + 12] = '0';
            }
        }
    }

    /* Add function information to symbol */
    for (i = 0; i < 9; i++) {
        if (function_information[i] == '1') {
            grid[(8 * size) + i] = 0x01;
            grid[((size - 8 - 1) * size) + (size - i - 1)] = 0x01;
        }
        if (function_information[i + 8] == '1') {
            grid[((8 - i) * size) + 8] = 0x01;
            grid[((size - 8 - 1 + i) * size) + (size - 8 - 1)] = 0x01;
        }
        if (function_information[i + 17] == '1') {
            grid[(i * size) + (size - 1 - 8)] = 0x01;
            grid[((size - 1 - i) * size) + 8] = 0x01;
        }
        if (function_information[i + 25] == '1') {
            grid[(8 * size) + (size - 1 - 8 + i)] = 0x01;
            grid[((size - 1 - 8) * size) + (8 - i)] = 0x01;
        }
    }

    symbol->width = size;
    symbol->rows = size;

    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            if (grid[(i * size) + j] & 0x01) {
                set_module(symbol, i, j);
            }
        }
        symbol->row_height[i] = 1;
    }

    return 0;
}
Added jni/zint/backend/hanxin.h.
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
/*  hanxin.h - definitions for Han Xin code

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>
    Copyright (C) 2016 Zoe Stuart

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

/* Data from table B1: Data capacity of Han Xin Code */
static const int hx_total_codewords[] = {
    25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249,
    273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660,
    698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175,
    1224, 1275, 1327, 1380, 1434, 1489, 1513, 1569, 1628, 1686, 1745, 1805,
    1867, 1929, 1992, 2021, 2086, 2151, 2218, 2286, 2355, 2425, 2496, 2528,
    2600, 2673, 2749, 2824, 2900, 2977, 3056, 3135, 3171, 3252, 3334, 3416,
    3500, 3585, 3671, 3758, 3798, 3886
};

static const int hx_data_codewords_L1[] = {
    21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229,
    251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619,
    634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115,
    1160, 1204, 1251, 1271, 1317, 1368, 1416, 1465, 1517, 1569, 1621, 1674,
    1697, 1752, 1807, 1864, 1920, 1979, 2037, 2096, 2124, 2184, 2245, 2309,
    2372, 2436, 2501, 2568, 2633, 2663, 2732, 2800, 2870, 2940, 3011,
    3083, 3156, 3190, 3264
};

static const int hx_data_codewords_L2[] = {
    17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209,
    227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528,
    556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004,
    1043, 1059, 1099, 1140, 1180, 1221, 1263, 1307, 1351, 1394, 1415, 1460,
    1505, 1552, 1600, 1649, 1697, 1748, 1770, 1820, 1871, 1925, 1976, 2030,
    2083, 2140, 2195, 2219, 2276, 2334, 2392, 2450, 2509, 2569, 2630, 2658,
    2720
};

static const int hx_data_codewords_L3[] = {
    13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161,
    175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408,
    428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774,
    805, 817, 847, 880, 910, 943, 975, 1009, 1041, 1076, 1091, 1126, 1161, 1198,
    1234, 1271, 1309, 1348, 1366, 1404, 1443, 1485, 1524, 1566, 1607, 1650, 1693,
    1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098
};

static const int hx_data_codewords_L4[] = {
    9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129,
    141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318,
    334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605,
    627, 652, 674, 697, 721, 747, 771, 796, 809, 834, 861, 892, 914, 941, 969, 998,
    1012, 1040, 1069, 1099, 1130, 1160, 1191, 1222, 1253, 1269, 1300, 1334,
    1366, 1400, 1433, 1469, 1504, 1520, 1554
};

/* Value 'k' from Annex A */
static const int hx_module_k[] = {
    0, 0, 0, 14, 16, 16, 17, 18, 19, 20,
    14, 15, 16, 16, 17, 17, 18, 19, 20, 20,
    21, 16, 17, 17, 18, 18, 19, 19, 20, 20,
    21, 17, 17, 18, 18, 19, 19, 19, 20, 20,
    17, 17, 18, 18, 18, 19, 19, 19, 17, 17,
    18, 18, 18, 18, 19, 19, 19, 17, 17, 18,
    18, 18, 18, 19, 19, 17, 17, 17, 18, 18,
    18, 18, 19, 19, 17, 17, 17, 18, 18, 18,
    18, 18, 17, 17
};

/* Value 'r' from Annex A */
static const int hx_module_r[] = {
    0, 0, 0, 15, 15, 17, 18, 19, 20, 21,
    15, 15, 15, 17, 17, 19, 19, 19, 19, 21,
    21, 17, 16, 18, 17, 19, 18, 20, 19, 21,
    20, 17, 19, 17, 19, 17, 19, 21, 19, 21,
    18, 20, 17, 19, 21, 18, 20, 22, 17, 19,
    15, 17, 19, 21, 17, 19, 21, 18, 20, 15,
    17, 19, 21, 16, 18, 17, 19, 21, 15, 17,
    19, 21, 15, 17, 18, 20, 22, 15, 17, 19,
    21, 23, 17, 19
};

/* Value of 'm' from Annex A */
static const int hx_module_m[] = {
    0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
    6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
    7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
    8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
    9, 9, 10, 10
};

/* Error correction block sizes from Table D1 */
static const int hx_table_d1[] = {
    /* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */
    1, 21, 4, 0, 0, 0, 0, 0, 0, // version 1
    1, 17, 8, 0, 0, 0, 0, 0, 0,
    1, 13, 12, 0, 0, 0, 0, 0, 0,
    1, 9, 16, 0, 0, 0, 0, 0, 0,
    1, 31, 6, 0, 0, 0, 0, 0, 0, // version 2
    1, 25, 12, 0, 0, 0, 0, 0, 0,
    1, 19, 18, 0, 0, 0, 0, 0, 0,
    1, 15, 22, 0, 0, 0, 0, 0, 0,
    1, 42, 8, 0, 0, 0, 0, 0, 0, // version 3
    1, 34, 16, 0, 0, 0, 0, 0, 0,
    1, 26, 24, 0, 0, 0, 0, 0, 0,
    1, 20, 30, 0, 0, 0, 0, 0, 0,
    1, 46, 8, 0, 0, 0, 0, 0, 0, // version 4
    1, 38, 16, 0, 0, 0, 0, 0, 0,
    1, 30, 24, 0, 0, 0, 0, 0, 0,
    1, 22, 32, 0, 0, 0, 0, 0, 0,
    1, 57, 12, 0, 0, 0, 0, 0, 0, // version 5
    1, 49, 20, 0, 0, 0, 0, 0, 0,
    1, 37, 32, 0, 0, 0, 0, 0, 0,
    1, 14, 20, 1, 13, 22, 0, 0, 0,
    1, 70, 14, 0, 0, 0, 0, 0, 0, // version 6
    1, 58, 26, 0, 0, 0, 0, 0, 0,
    1, 24, 20, 1, 22, 18, 0, 0, 0,
    1, 16, 24, 1, 18, 26, 0, 0, 0,
    1, 84, 16, 0, 0, 0, 0, 0, 0, // version 7
    1, 70, 30, 0, 0, 0, 0, 0, 0,
    1, 26, 22, 1, 28, 24, 0, 0, 0,
    2, 14, 20, 1, 12, 20, 0, 0, 0,
    1, 99, 18, 0, 0, 0, 0, 0, 0, // version 8
    1, 40, 18, 1, 41, 18, 0, 0, 0,
    1, 31, 26, 1, 32, 28, 0, 0, 0,
    2, 16, 24, 1, 15, 22, 0, 0, 0,
    1, 114, 22, 0, 0, 0, 0, 0, 0, // version 9
    2, 48, 20, 0, 0, 0, 0, 0, 0,
    2, 24, 20, 1, 26, 22, 0, 0, 0,
    2, 18, 28, 1, 18, 26, 0, 0, 0,
    1, 131, 24, 0, 0, 0, 0, 0, 0, // version 10
    1, 52, 22, 1, 57, 24, 0, 0, 0,
    2, 27, 24, 1, 29, 24, 0, 0, 0,
    2, 21, 32, 1, 19, 30, 0, 0, 0,
    1, 135, 26, 0, 0, 0, 0, 0, 0, // version 11
    1, 56, 24, 1, 57, 24, 0, 0, 0,
    2, 28, 24, 1, 31, 26, 0, 0, 0,
    2, 22, 32, 1, 21, 32, 0, 0, 0,
    1, 153, 28, 0, 0, 0, 0, 0, 0, // version 12
    1, 62, 26, 1, 65, 28, 0, 0, 0,
    2, 32, 28, 1, 33, 28, 0, 0, 0,
    3, 17, 26, 1, 22, 30, 0, 0, 0,
    1, 86, 16, 1, 85, 16, 0, 0, 0, // version 13
    1, 71, 30, 1, 72, 30, 0, 0, 0,
    2, 37, 32, 1, 35, 30, 0, 0, 0,
    3, 20, 30, 1, 21, 32, 0, 0, 0,
    1, 94, 18, 1, 95, 18, 0, 0, 0, // version 14
    2, 51, 22, 1, 55, 24, 0, 0, 0,
    3, 30, 26, 1, 31, 26, 0, 0, 0,
    4, 18, 28, 1, 17, 24, 0, 0, 0,
    1, 104, 20, 1, 105, 20, 0, 0, 0, // version 15
    2, 57, 24, 1, 61, 26, 0, 0, 0,
    3, 33, 28, 1, 36, 30, 0, 0, 0,
    4, 20, 30, 1, 19, 30, 0, 0, 0,
    1, 115, 22, 1, 114, 22, 0, 0, 0, // version 16
    2, 65, 28, 1, 61, 26, 0, 0, 0,
    3, 38, 32, 1, 33, 30, 0, 0, 0,
    5, 19, 28, 1, 14, 24, 0, 0, 0,
    1, 126, 24, 1, 125, 24, 0, 0, 0, // version 17
    2, 70, 30, 1, 69, 30, 0, 0, 0,
    4, 33, 28, 1, 29, 26, 0, 0, 0,
    5, 20, 30, 1, 19, 30, 0, 0, 0,
    1, 136, 26, 1, 137, 26, 0, 0, 0, //version 18
    3, 56, 24, 1, 59, 26, 0, 0, 0,
    5, 35, 30, 0, 0, 0, 0, 0, 0,
    6, 18, 28, 1, 21, 28, 0, 0, 0,
    1, 148, 28, 1, 149, 28, 0, 0, 0, // version 19
    3, 61, 26, 1, 64, 28, 0, 0, 0,
    7, 24, 20, 1, 23, 22, 0, 0, 0,
    6, 20, 30, 1, 21, 32, 0, 0, 0,
    3, 107, 20, 0, 0, 0, 0, 0, 0, // version 20
    3, 65, 28, 1, 72, 30, 0, 0, 0,
    7, 26, 22, 1, 23, 22, 0, 0, 0,
    7, 19, 28, 1, 20, 32, 0, 0, 0,
    3, 115, 22, 0, 0, 0, 0, 0, 0, // version 21
    4, 56, 24, 1, 63, 28, 0, 0, 0,
    7, 28, 24, 1, 25, 22, 0, 0, 0,
    8, 18, 28, 1, 21, 22, 0, 0, 0,
    2, 116, 22, 1, 122, 24, 0, 0, 0, // version 22
    4, 56, 24, 1, 72, 30, 0, 0, 0,
    7, 28, 24, 1, 32, 26, 0, 0, 0,
    8, 18, 28, 1, 24, 30, 0, 0, 0,
    3, 127, 24, 0, 0, 0, 0, 0, 0, // version 23
    5, 51, 22, 1, 62, 26, 0, 0, 0,
    7, 30, 26, 1, 35, 26, 0, 0, 0,
    8, 20, 30, 1, 21, 32, 0, 0, 0,
    2, 135, 26, 1, 137, 26, 0, 0, 0, // version 24
    5, 56, 24, 1, 59, 26, 0, 0, 0,
    7, 33, 28, 1, 30, 28, 0, 0, 0,
    11, 16, 24, 1, 19, 26, 0, 0, 0,
    3, 105, 20, 1, 121, 22, 0, 0, 0, // version 25
    5, 61, 26, 1, 57, 26, 0, 0, 0,
    9, 28, 24, 1, 28, 22, 0, 0, 0,
    10, 19, 28, 1, 18, 30, 0, 0, 0,
    2, 157, 30, 1, 150, 28, 0, 0, 0, // version 26
    5, 65, 28, 1, 61, 26, 0, 0, 0,
    8, 33, 28, 1, 34, 30, 0, 0, 0,
    10, 19, 28, 2, 15, 26, 0, 0, 0,
    3, 126, 24, 1, 115, 22, 0, 0, 0, // version 27
    7, 51, 22, 1, 54, 22, 0, 0, 0,
    8, 35, 30, 1, 37, 30, 0, 0, 0,
    15, 15, 22, 1, 10, 22, 0, 0, 0,
    4, 105, 20, 1, 103, 20, 0, 0, 0, // version 28
    7, 56, 24, 1, 45, 18, 0, 0, 0,
    10, 31, 26, 1, 27, 26, 0, 0, 0,
    10, 17, 26, 3, 20, 28, 1, 21, 28,
    3, 139, 26, 1, 137, 28, 0, 0, 0, // version 29
    6, 66, 28, 1, 66, 30, 0, 0, 0,
    9, 36, 30, 1, 34, 32, 0, 0, 0,
    13, 19, 28, 1, 17, 32, 0, 0, 0,
    6, 84, 16, 1, 82, 16, 0, 0, 0, // version 30
    6, 70, 30, 1, 68, 30, 0, 0, 0,
    7, 35, 30, 3, 33, 28, 1, 32, 28,
    13, 20, 30, 1, 20, 28, 0, 0, 0,
    5, 105, 20, 1, 94, 18, 0, 0, 0, // version 31
    6, 74, 32, 1, 71, 30, 0, 0, 0,
    11, 33, 28, 1, 34, 32, 0, 0, 0,
    13, 19, 28, 3, 16, 26, 0, 0, 0,
    4, 127, 24, 1, 126, 24, 0, 0, 0, // version 32
    7, 66, 28, 1, 66, 30, 0, 0, 0,
    12, 30, 24, 1, 24, 28, 1, 24, 30,
    15, 19, 28, 1, 17, 32, 0, 0, 0,
    7, 84, 16, 1, 78, 16, 0, 0, 0, // version 33
    7, 70, 30, 1, 66, 28, 0, 0, 0,
    12, 33, 28, 1, 32, 30, 0, 0, 0,
    14, 21, 32, 1, 24, 28, 0, 0, 0,
    5, 117, 22, 1, 117, 24, 0, 0, 0, // version 34
    8, 66, 28, 1, 58, 26, 0, 0, 0,
    11, 38, 32, 1, 34, 32, 0, 0, 0,
    15, 20, 30, 2, 17, 26, 0, 0, 0,
    4, 148, 28, 1, 146, 28, 0, 0, 0, // version 35
    8, 68, 30, 1, 70, 24, 0, 0, 0,
    10, 36, 32, 3, 38, 28, 0, 0, 0,
    16, 19, 28, 3, 16, 26, 0, 0, 0,
    4, 126, 24, 2, 135, 26, 0, 0, 0, // version 36
    8, 70, 28, 2, 43, 26, 0, 0, 0,
    13, 32, 28, 2, 41, 30, 0, 0, 0,
    17, 19, 28, 3, 15, 26, 0, 0, 0,
    5, 136, 26, 1, 132, 24, 0, 0, 0, // version 37
    5, 67, 30, 4, 68, 28, 1, 69, 28,
    14, 35, 30, 1, 32, 24, 0, 0, 0,
    18, 18, 26, 3, 16, 28, 1, 14, 28,
    3, 142, 26, 3, 141, 28, 0, 0, 0, // version 38
    8, 70, 30, 1, 73, 32, 1, 74, 32,
    12, 34, 30, 3, 34, 26, 1, 35, 28,
    18, 21, 32, 1, 27, 30, 0, 0, 0,
    5, 116, 22, 2, 103, 20, 1, 102, 20, // version 39
    9, 74, 32, 1, 74, 30, 0, 0, 0,
    14, 34, 28, 2, 32, 32, 1, 32, 30,
    19, 21, 32, 1, 25, 26, 0, 0, 0,
    7, 116, 22, 1, 117, 22, 0, 0, 0, // version 40
    11, 65, 28, 1, 58, 24, 0, 0, 0,
    15, 38, 32, 1, 27, 28, 0, 0, 0,
    20, 20, 30, 1, 20, 32, 1, 21, 32,
    6, 136, 26, 1, 130, 24, 0, 0, 0, // version 41
    11, 66, 28, 1, 62, 30, 0, 0, 0,
    14, 34, 28, 3, 34, 32, 1, 30, 30,
    18, 20, 30, 3, 20, 28, 2, 15, 26,
    5, 105, 20, 2, 115, 22, 2, 116, 22, // version 42
    10, 75, 32, 1, 73, 32, 0, 0, 0,
    16, 38, 32, 1, 27, 28, 0, 0, 0,
    22, 19, 28, 2, 16, 30, 1, 19, 30,
    6, 147, 28, 1, 146, 28, 0, 0, 0, // version 43
    11, 66, 28, 2, 65, 30, 0, 0, 0,
    18, 33, 28, 2, 33, 30, 0, 0, 0,
    22, 21, 32, 1, 28, 30, 0, 0, 0,
    6, 116, 22, 3, 125, 24, 0, 0, 0, // version 44
    11, 75, 32, 1, 68, 30, 0, 0, 0,
    13, 35, 28, 6, 34, 32, 1, 30, 30,
    23, 21, 32, 1, 26, 30, 0, 0, 0,
    7, 105, 20, 4, 95, 18, 0, 0, 0, // version 45
    12, 67, 28, 1, 63, 30, 1, 62, 32,
    21, 31, 26, 2, 33, 32, 0, 0, 0,
    23, 21, 32, 2, 24, 30, 0, 0, 0,
    10, 116, 22, 0, 0, 0, 0, 0, 0, // version 46
    12, 74, 32, 1, 78, 30, 0, 0, 0,
    18, 37, 32, 1, 39, 30, 1, 41, 28,
    25, 21, 32, 1, 27, 28, 0, 0, 0,
    5, 126, 24, 4, 115, 22, 1, 114, 22, // version 47
    12, 67, 28, 2, 66, 32, 1, 68, 30,
    21, 35, 30, 1, 39, 30, 0, 0, 0,
    26, 21, 32, 1, 28, 28, 0, 0, 0,
    9, 126, 24, 1, 117, 22, 0, 0, 0, // version 48
    13, 75, 32, 1, 68, 30, 0, 0, 0,
    20, 35, 30, 3, 35, 28, 0, 0, 0,
    27, 21, 32, 1, 28, 30, 0, 0, 0,
    9, 126, 24, 1, 137, 26, 0, 0, 0, // version 49
    13, 71, 30, 2, 68, 32, 0, 0, 0,
    20, 37, 32, 1, 39, 28, 1, 38, 28,
    24, 20, 32, 5, 25, 28, 0, 0, 0,
    8, 147, 28, 1, 141, 28, 0, 0, 0, // version 50
    10, 73, 32, 4, 74, 30, 1, 73, 30,
    16, 36, 32, 6, 39, 30, 1, 37, 30,
    27, 21, 32, 3, 20, 26, 0, 0, 0,
    9, 137, 26, 1, 135, 26, 0, 0, 0, // version 51
    12, 70, 30, 4, 75, 32, 0, 0, 0,
    24, 35, 30, 1, 40, 28, 0, 0, 0,
    23, 20, 32, 8, 24, 30, 0, 0, 0,
    14, 95, 18, 1, 86, 18, 0, 0, 0, // version 52
    13, 73, 32, 3, 77, 30, 0, 0, 0,
    24, 35, 30, 2, 35, 28, 0, 0, 0,
    26, 21, 32, 5, 21, 30, 1, 23, 30,
    9, 147, 28, 1, 142, 28, 0, 0, 0, // version 53
    10, 73, 30, 6, 70, 32, 1, 71, 32,
    25, 35, 30, 2, 34, 26, 0, 0, 0,
    29, 21, 32, 4, 22, 30, 0, 0, 0,
    11, 126, 24, 1, 131, 24, 0, 0, 0, // version 54
    16, 74, 32, 1, 79, 30, 0, 0, 0,
    25, 38, 32, 1, 25, 30, 0, 0, 0,
    33, 21, 32, 1, 28, 28, 0, 0, 0,
    14, 105, 20, 1, 99, 18, 0, 0, 0, // version 55
    19, 65, 28, 1, 72, 28, 0, 0, 0,
    24, 37, 32, 2, 40, 30, 1, 41, 30,
    31, 21, 32, 4, 24, 32, 0, 0, 0,
    10, 147, 28, 1, 151, 28, 0, 0, 0, // version 56
    15, 71, 30, 3, 71, 32, 1, 73, 32,
    24, 37, 32, 3, 38, 30, 1, 39, 30,
    36, 19, 30, 3, 29, 26, 0, 0, 0,
    15, 105, 20, 1, 99, 18, 0, 0, 0, // version 57
    19, 70, 30, 1, 64, 28, 0, 0, 0,
    27, 38, 32, 2, 25, 26, 0, 0, 0,
    38, 20, 30, 2, 18, 28, 0, 0, 0,
    14, 105, 20, 1, 113, 22, 1, 114, 22, // version 58
    17, 67, 30, 3, 92, 32, 0, 0, 0,
    30, 35, 30, 1, 41, 30, 0, 0, 0,
    36, 21, 32, 1, 26, 30, 1, 27, 30,
    11, 146, 28, 1, 146, 26, 0, 0, 0, // version 59
    20, 70, 30, 1, 60, 26, 0, 0, 0,
    29, 38, 32, 1, 24, 32, 0, 0, 0,
    40, 20, 30, 2, 17, 26, 0, 0, 0,
    3, 137, 26, 1, 136, 26, 10, 126, 24, // version 60
    22, 65, 28, 1, 75, 30, 0, 0, 0,
    30, 37, 32, 1, 51, 30, 0, 0, 0,
    42, 20, 30, 1, 21, 30, 0, 0, 0,
    12, 126, 24, 2, 118, 22, 1, 116, 22, // version 61
    19, 74, 32, 1, 74, 30, 1, 72, 28,
    30, 38, 32, 2, 29, 30, 0, 0, 0,
    39, 20, 32, 2, 37, 26, 1, 38, 26,
    12, 126, 24, 3, 136, 26, 0, 0, 0, // version 62
    21, 70, 30, 2, 65, 28, 0, 0, 0,
    34, 35, 30, 1, 44, 32, 0, 0, 0,
    42, 20, 30, 2, 19, 28, 2, 18, 28,
    12, 126, 24, 3, 117, 22, 1, 116, 22, // version 63
    25, 61, 26, 2, 62, 28, 0, 0, 0,
    34, 35, 30, 1, 40, 32, 1, 41, 32,
    45, 20, 30, 1, 20, 32, 1, 21, 32,
    15, 105, 20, 2, 115, 22, 2, 116, 22, // version 64
    25, 65, 28, 1, 72, 28, 0, 0, 0,
    18, 35, 30, 17, 37, 32, 1, 50, 32,
    42, 20, 30, 6, 19, 28, 1, 15, 28,
    19, 105, 20, 1, 101, 20, 0, 0, 0, // version 65
    33, 51, 22, 1, 65, 22, 0, 0, 0,
    40, 33, 28, 1, 28, 28, 0, 0, 0,
    49, 20, 30, 1, 18, 28, 0, 0, 0,
    18, 105, 20, 2, 117, 22, 0, 0, 0, // version 66
    26, 65, 28, 1, 80, 30, 0, 0, 0,
    35, 35, 30, 3, 35, 28, 1, 36, 28,
    52, 18, 28, 2, 38, 30, 0, 0, 0,
    26, 84, 16, 0, 0, 0, 0, 0, 0, // version 67
    26, 70, 30, 0, 0, 0, 0, 0, 0,
    45, 31, 26, 1, 9, 26, 0, 0, 0,
    52, 20, 30, 0, 0, 0, 0, 0, 0,
    16, 126, 24, 1, 114, 22, 1, 115, 22, // version 68
    23, 70, 30, 3, 65, 28, 1, 66, 28,
    40, 35, 30, 1, 43, 30, 0, 0, 0,
    46, 20, 30, 7, 19, 28, 1, 16, 28,
    19, 116, 22, 1, 105, 22, 0, 0, 0, // version 69
    20, 70, 30, 7, 66, 28, 1, 63, 28,
    40, 35, 30, 1, 42, 32, 1, 43, 32,
    54, 20, 30, 1, 19, 30, 0, 0, 0,
    17, 126, 24, 2, 115, 22, 0, 0, 0, // version 70
    24, 70, 30, 4, 74, 32, 0, 0, 0,
    48, 31, 26, 2, 18, 26, 0, 0, 0,
    54, 19, 28, 6, 15, 26, 1, 14, 26,
    29, 84, 16, 0, 0, 0, 0, 0, 0, // version 71
    29, 70, 30, 0, 0, 0, 0, 0, 0,
    6, 34, 30, 3, 36, 30, 38, 33, 28,
    58, 20, 30, 0, 0, 0, 0, 0, 0,
    16, 147, 28, 1, 149, 28, 0, 0, 0, // version 72
    31, 66, 28, 1, 37, 26, 0, 0, 0,
    48, 33, 28, 1, 23, 26, 0, 0, 0,
    53, 20, 30, 6, 19, 28, 1, 17, 28,
    20, 115, 22, 2, 134, 24, 0, 0, 0, // verdion 73
    29, 66, 28, 2, 56, 26, 2, 57, 26,
    45, 36, 30, 2, 15, 28, 0, 0, 0,
    59, 20, 30, 2, 21, 32, 0, 0, 0,
    17, 147, 28, 1, 134, 26, 0, 0, 0, // version 74
    26, 70, 30, 5, 75, 32, 0, 0, 0,
    47, 35, 30, 1, 48, 32, 0, 0, 0,
    64, 18, 28, 2, 33, 30, 1, 35, 30,
    22, 115, 22, 1, 133, 24, 0, 0, 0, // version 75
    33, 65, 28, 1, 74, 28, 0, 0, 0,
    43, 36, 30, 5, 27, 28, 1, 30, 28,
    57, 20, 30, 5, 21, 32, 1, 24, 32,
    18, 136, 26, 2, 142, 26, 0, 0, 0, // version 76
    33, 66, 28, 2, 49, 26, 0, 0, 0,
    48, 35, 30, 2, 38, 28, 0, 0, 0,
    64, 20, 30, 1, 20, 32, 0, 0, 0,
    19, 126, 24, 2, 135, 26, 1, 136, 26, // version 77
    32, 66, 28, 2, 55, 26, 2, 56, 26,
    49, 36, 30, 2, 18, 32, 0, 0, 0,
    65, 18, 28, 5, 27, 30, 1, 29, 30,
    20, 137, 26, 1, 130, 26, 0, 0, 0, // version 78
    30, 75, 32, 2, 71, 32, 0, 0, 0,
    46, 35, 30, 6, 39, 32, 0, 0, 0,
    3, 12, 30, 70, 19, 28, 0, 0, 0,
    20, 147, 28, 0, 0, 0, 0, 0, 0, // version 79
    35, 70, 30, 0, 0, 0, 0, 0, 0,
    49, 35, 30, 5, 35, 28, 0, 0, 0,
    70, 20, 30, 0, 0, 0, 0, 0, 0,
    21, 136, 26, 1, 155, 28, 0, 0, 0, // version 80
    34, 70, 30, 1, 64, 28, 1, 65, 28,
    54, 35, 30, 1, 45, 30, 0, 0, 0,
    68, 20, 30, 3, 18, 28, 1, 19, 28,
    19, 126, 24, 5, 115, 22, 1, 114, 22, // version 81
    33, 70, 30, 3, 65, 28, 1, 64, 28,
    52, 35, 30, 3, 41, 32, 1, 40, 32,
    67, 20, 30, 5, 21, 32, 1, 24, 32,
    2, 150, 28, 21, 136, 26, 0, 0, 0, // version 82
    32, 70, 30, 6, 65, 28, 0, 0, 0,
    52, 38, 32, 2, 27, 32, 0, 0, 0,
    73, 20, 30, 2, 22, 32, 0, 0, 0,
    21, 126, 24, 4, 136, 26, 0, 0, 0, // version 83
    30, 74, 32, 6, 73, 30, 0, 0, 0,
    54, 35, 30, 4, 40, 32, 0, 0, 0,
    75, 20, 30, 1, 20, 28, 0, 0, 0,
    30, 105, 20, 1, 114, 22, 0, 0, 0, // version 84
    3, 45, 22, 55, 47, 20, 0, 0, 0,
    2, 26, 26, 62, 33, 28, 0, 0, 0,
    79, 18, 28, 4, 33, 30, 0, 0, 0
};
Changes to jni/zint/backend/imail.c.
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
            FrameCheckSequence &= 0x7FF;
            Data <<= 1;
        }
    }
    return FrameCheckSequence;
}

void breakup(short int fcs_bit[], unsigned short usps_crc) {
    int i;

    for (i = 0; i < 13; i++) {
        fcs_bit[i] = 0;
    }

    if (usps_crc >= 4096) {
        fcs_bit[12] = 1;
        usps_crc -= 4096;
    }
    if (usps_crc >= 2048) {
        fcs_bit[11] = 1;
        usps_crc -= 2048;
    }
    if (usps_crc >= 1024) {
        fcs_bit[10] = 1;
        usps_crc -= 1024;
    }
    if (usps_crc >= 512) {
        fcs_bit[9] = 1;
        usps_crc -= 512;
    }
    if (usps_crc >= 256) {
        fcs_bit[8] = 1;
        usps_crc -= 256;
    }
    if (usps_crc >= 128) {
        fcs_bit[7] = 1;
        usps_crc -= 128;
    }
    if (usps_crc >= 64) {
        fcs_bit[6] = 1;
        usps_crc -= 64;
    }
    if (usps_crc >= 32) {
        fcs_bit[5] = 1;
        usps_crc -= 32;
    }
    if (usps_crc >= 16) {
        fcs_bit[4] = 1;
        usps_crc -= 16;
    }
    if (usps_crc >= 8) {
        fcs_bit[3] = 1;
        usps_crc -= 8;
    }
    if (usps_crc >= 4) {
        fcs_bit[2] = 1;
        usps_crc -= 4;
    }
    if (usps_crc >= 2) {
        fcs_bit[1] = 1;
        usps_crc -= 2;
    }
    if (usps_crc == 1) {
        fcs_bit[0] = 1;
    }
}

int imail(struct zint_symbol *symbol, unsigned char source[], int length) {
    char data_pattern[200];
    int error_number;
    int i, j, read;
    char zip[35], tracker[35], zip_adder[11], temp[2];
    short int accum[112], x_reg[112], y_reg[112];
    unsigned char byte_array[13];
    unsigned short usps_crc;
    int codeword[10];
    unsigned short characters[10];
    short int bit_pattern[13], bar_map[130];

    error_number = 0;

    if (length > 32) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SODIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    strcpy(zip, "");
    strcpy(tracker, "");

    /* separate the tracking code from the routing code */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|




|




|







252
253
254
255
256
257
258




























































259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
            FrameCheckSequence &= 0x7FF;
            Data <<= 1;
        }
    }
    return FrameCheckSequence;
}





























































int imail(struct zint_symbol *symbol, unsigned char source[], int length) {
    char data_pattern[200];
    int error_number;
    int i, j, read;
    char zip[35], tracker[35], zip_adder[11], temp[2];
    short int accum[112], x_reg[112], y_reg[112];
    unsigned char byte_array[13];
    unsigned short usps_crc;
    int codeword[10];
    unsigned short characters[10];
    short int bar_map[130];

    error_number = 0;

    if (length > 32) {
        strcpy(symbol->errtxt, "Input too long (D50)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SODIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D51)");
        return error_number;
    }

    strcpy(zip, "");
    strcpy(tracker, "");

    /* separate the tracking code from the routing code */
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
    if (j == 0) {
        tracker[read] = '\0';
    } else {
        zip[read] = '\0';
    }

    if (strlen(tracker) != 20) {
        strcpy(symbol->errtxt, "Invalid length tracking code");
        return ZINT_ERROR_INVALID_DATA;
    }
    if (strlen(zip) > 11) {
        strcpy(symbol->errtxt, "Invalid ZIP code");
        return ZINT_ERROR_INVALID_DATA;
    }

    /* *** Step 1 - Conversion of Data Fields into Binary Data *** */

    /* Routing code first */








|



|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    if (j == 0) {
        tracker[read] = '\0';
    } else {
        zip[read] = '\0';
    }

    if (strlen(tracker) != 20) {
        strcpy(symbol->errtxt, "Invalid length tracking code (D52)");
        return ZINT_ERROR_INVALID_DATA;
    }
    if (strlen(zip) > 11) {
        strcpy(symbol->errtxt, "Invalid ZIP code (D53)");
        return ZINT_ERROR_INVALID_DATA;
    }

    /* *** Step 1 - Conversion of Data Fields into Binary Data *** */

    /* Routing code first */

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

642



643
644
645
646
647
648
649
    for (i = 0; i < 10; i++) {
        if (codeword[i] < 1287) {
            characters[i] = AppxD_I[codeword[i]];
        } else {
            characters[i] = AppxD_II[codeword[i] - 1287];
        }
    }

    breakup(bit_pattern, usps_crc);

    for (i = 0; i < 10; i++) {
        if (bit_pattern[i] == 1) {
            characters[i] = 0x1FFF - characters[i];
        }
    }

    /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */

    for (i = 0; i < 10; i++) {
        breakup(bit_pattern, characters[i]);
        for (j = 0; j < 13; j++) {

            bar_map[AppxD_IV[(13 * i) + j] - 1] = bit_pattern[j];



        }
    }

    strcpy(data_pattern, "");
    temp[1] = '\0';
    for (i = 0; i < 65; i++) {
        j = 0;







|
<
<

|





<

<

>
|
>
>
>







561
562
563
564
565
566
567
568


569
570
571
572
573
574
575

576

577
578
579
580
581
582
583
584
585
586
587
588
589
    for (i = 0; i < 10; i++) {
        if (codeword[i] < 1287) {
            characters[i] = AppxD_I[codeword[i]];
        } else {
            characters[i] = AppxD_II[codeword[i] - 1287];
        }
    }
    


    for (i = 0; i < 10; i++) {
        if (usps_crc & (1 << i)) {
            characters[i] = 0x1FFF - characters[i];
        }
    }

    /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */

    for (i = 0; i < 10; i++) {

        for (j = 0; j < 13; j++) {
            if (characters[i] & (1 << j)) {
                bar_map[AppxD_IV[(13 * i) + j] - 1] = 1;
            } else {
                bar_map[AppxD_IV[(13 * i) + j] - 1] = 0;
            }
        }
    }

    strcpy(data_pattern, "");
    temp[1] = '\0';
    for (i = 0; i < 65; i++) {
        j = 0;
Changes to jni/zint/backend/library.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
















123
124
125
126
127
128
129



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "common.h"
#include "gs1.h"

#define TECHNETIUM	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"

struct zint_symbol *ZBarcode_Create() {
    struct zint_symbol *symbol;
    int i;

    symbol = (struct zint_symbol*) malloc(sizeof (*symbol));
    if (!symbol) return NULL;

    memset(symbol, 0, sizeof (*symbol));
    symbol->symbology = BARCODE_CODE128;
    symbol->height = 0;
    symbol->whitespace_width = 0;
    symbol->border_width = 0;
    symbol->output_options = 0;
    symbol->rows = 0;
    symbol->width = 0;
    strcpy(symbol->fgcolour, "000000");
    strcpy(symbol->bgcolour, "ffffff");
    strcpy(symbol->outfile, "");
    symbol->scale = 1.0;
    symbol->option_1 = -1;
    symbol->option_2 = 0;
    symbol->option_3 = 928; // PDF_MAX
    symbol->show_hrt = 1; // Show human readable text
    symbol->input_mode = DATA_MODE;
    strcpy(symbol->primary, "");
    memset(&(symbol->encoded_data[0][0]), 0, sizeof (symbol->encoded_data));
    for (i = 0; i < 178; i++) {
        symbol->row_height[i] = 0;
    }
    symbol->bitmap = NULL;
    symbol->bitmap_width = 0;
    symbol->bitmap_height = 0;


    return symbol;
}

void ZBarcode_Clear(struct zint_symbol *symbol) {
    int i, j;

    for (i = 0; i < symbol->rows; i++) {
        for (j = 0; j < symbol->width; j++) {
            unset_module(symbol, i, j);
        }
    }
    symbol->rows = 0;
    symbol->width = 0;
    memset(symbol->text, 0, 128);
    symbol->errtxt[0] = '\0';
    if (symbol->bitmap != NULL) {
        free(symbol->bitmap);
        symbol->bitmap = NULL;
    }
    symbol->bitmap_width = 0;
    symbol->bitmap_height = 0;
}

void ZBarcode_Delete(struct zint_symbol *symbol) {
    if (symbol->bitmap != NULL)
        free(symbol->bitmap);

    // If there is a rendered version, ensure its memory is released
    if (symbol->rendered != NULL) {
        struct zint_render_line *line, *l;
        struct zint_render_string *string, *s;



        // Free lines
        line = symbol->rendered->lines;
        while (line) {
            l = line;
            line = line->next;
            free(l);
        }
        // Free Strings
        string = symbol->rendered->strings;
        while (string) {
            s = string;
            string = string->next;
            free(s->text);
            free(s);
        }

















        // Free Render
        free(symbol->rendered);
    }
    free(symbol);
}




extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */
extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */
extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */
extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */
extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */
extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */
extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */
extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */
extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */
extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */
extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */
extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */
extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */
extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */
extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */
extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */
extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */
extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */
extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */
extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */
extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */
extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */
extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */
extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */
extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */
extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */
extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */
extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */
extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */
extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */
extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */
extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */
extern int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */
extern int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length); /* QR Code */
extern int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */
extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */
extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */
extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */







<






|
















<
|
<



>
>













|

















>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>

|






|






|
















|







39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "common.h"
#include "gs1.h"

#define TECHNETIUM	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"

struct zint_symbol *ZBarcode_Create() {
    struct zint_symbol *symbol;


    symbol = (struct zint_symbol*) malloc(sizeof (*symbol));
    if (!symbol) return NULL;

    memset(symbol, 0, sizeof (*symbol));
    symbol->symbology = BARCODE_CODE128;
    symbol->height = 50;
    symbol->whitespace_width = 0;
    symbol->border_width = 0;
    symbol->output_options = 0;
    symbol->rows = 0;
    symbol->width = 0;
    strcpy(symbol->fgcolour, "000000");
    strcpy(symbol->bgcolour, "ffffff");
    strcpy(symbol->outfile, "");
    symbol->scale = 1.0;
    symbol->option_1 = -1;
    symbol->option_2 = 0;
    symbol->option_3 = 928; // PDF_MAX
    symbol->show_hrt = 1; // Show human readable text
    symbol->input_mode = DATA_MODE;
    strcpy(symbol->primary, "");
    memset(&(symbol->encoded_data[0][0]), 0, sizeof (symbol->encoded_data));

    memset(&(symbol->row_height[0]), 0, sizeof (symbol->row_height));

    symbol->bitmap = NULL;
    symbol->bitmap_width = 0;
    symbol->bitmap_height = 0;
    symbol->eci = 3;
    symbol->dot_size = 4.0 / 5.0;
    return symbol;
}

void ZBarcode_Clear(struct zint_symbol *symbol) {
    int i, j;

    for (i = 0; i < symbol->rows; i++) {
        for (j = 0; j < symbol->width; j++) {
            unset_module(symbol, i, j);
        }
    }
    symbol->rows = 0;
    symbol->width = 0;
    memset(symbol->text, 0, sizeof(symbol->text));
    symbol->errtxt[0] = '\0';
    if (symbol->bitmap != NULL) {
        free(symbol->bitmap);
        symbol->bitmap = NULL;
    }
    symbol->bitmap_width = 0;
    symbol->bitmap_height = 0;
}

void ZBarcode_Delete(struct zint_symbol *symbol) {
    if (symbol->bitmap != NULL)
        free(symbol->bitmap);

    // If there is a rendered version, ensure its memory is released
    if (symbol->rendered != NULL) {
        struct zint_render_line *line, *l;
        struct zint_render_string *string, *s;
        struct zint_render_ring *ring, *r;
        struct zint_render_hexagon *hexagon, *h;

        // Free lines
        line = symbol->rendered->lines;
        while (line) {
            l = line;
            line = line->next;
            free(l);
        }
        // Free Strings
        string = symbol->rendered->strings;
        while (string) {
            s = string;
            string = string->next;
            free(s->text);
            free(s);
        }

        // Free Rings
        ring = symbol->rendered->rings;
        while (ring) {
            r = ring;
            ring = ring->next;
            free(r);
        }

        // Free Hexagons
        hexagon = symbol->rendered->hexagons;
        while (hexagon) {
            h = hexagon;
            hexagon = hexagon->next;
            free(h);
        }

        // Free Render
        free(symbol->rendered);
    }
    free(symbol);
}

extern int get_best_eci(unsigned char source[], int length); /* Calculate suitable ECI mode */
extern int utf_to_eci(int eci, const unsigned char source[], unsigned char dest[], int *length); /* Convert Unicode to other encodings */

extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */
extern int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 3 from 9 (or Code 39) */
extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */
extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */
extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */
extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */
extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */
extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */
extern int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Code 2 of 5 Interleaved */
extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */
extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */
extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */
extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */
extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */
extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */
extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */
extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */
extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */
extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */
extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */
extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */
extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */
extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */
extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */
extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */
extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */
extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */
extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */
extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */
extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */
extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */
extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */
extern int dmatrix(struct zint_symbol *symbol, const unsigned char source[], int length); /* Data Matrix (IEC16022) */
extern int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length); /* QR Code */
extern int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */
extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */
extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */
extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */
extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */
extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */
extern int code_49(struct zint_symbol *symbol, unsigned char source[], const int length); /* Code 49 */
extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */
extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */
extern int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], int length); /* Grid Matrix */

#ifndef NO_PNG
extern int png_handle(struct zint_symbol *symbol, int rotate_angle);
#endif


extern int render_plot(struct zint_symbol *symbol, float width, float height);

extern int bmp_handle(struct zint_symbol *symbol, int rotate_angle);
extern int ps_plot(struct zint_symbol *symbol);
extern int svg_plot(struct zint_symbol *symbol);

void error_tag(char error_string[], int error_number) {
    char error_buffer[100];

    if (error_number != 0) {
        strcpy(error_buffer, error_string);








|
|
|
<

>
|
<
<
|
|







197
198
199
200
201
202
203
204
205
206

207
208
209


210
211
212
213
214
215
216
217
218
extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */
extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */
extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */
extern int code_49(struct zint_symbol *symbol, unsigned char source[], const int length); /* Code 49 */
extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */
extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */
extern int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], int length); /* Grid Matrix */
extern int han_xin(struct zint_symbol * symbol, const unsigned char source[], int length); /* Han Xin */
extern int dotcode(struct zint_symbol * symbol, const unsigned char source[], int length); /* DotCode */
extern int codablock(struct zint_symbol * symbol, unsigned char source[], int length); /* Codablock */


extern int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */
extern int render_plot(struct zint_symbol *symbol, float width, float height); /* Plot to gLabels */


extern int ps_plot(struct zint_symbol *symbol); /* Plot to EPS */
extern int svg_plot(struct zint_symbol *symbol); /* Plot to SVG */

void error_tag(char error_string[], int error_number) {
    char error_buffer[100];

    if (error_number != 0) {
        strcpy(error_buffer, error_string);

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
    int space = 0;

    if (symbol->output_options & BARCODE_STDOUT) {
        f = stdout;
    } else {
        f = fopen(symbol->outfile, "w");
        if (!f) {
            strcpy(symbol->errtxt, "Could not open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    for (r = 0; r < symbol->rows; r++) {
        byt = 0;
        for (i = 0; i < symbol->width; i++) {







|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    int space = 0;

    if (symbol->output_options & BARCODE_STDOUT) {
        f = stdout;
    } else {
        f = fopen(symbol->outfile, "w");
        if (!f) {
            strcpy(symbol->errtxt, "Could not open output file (B01)");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    for (r = 0; r < symbol->rows; r++) {
        byt = 0;
        for (i = 0; i < symbol->width; i++) {
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
        fclose(f);
    }

    return 0;
}

/* Process health industry bar code data */
int hibc(struct zint_symbol *symbol, unsigned char source[], int length) {
    int counter, error_number, i;
    char to_process[40], temp[2], check_digit;


    if (length > 36) {
        strcpy(symbol->errtxt, "Data too long for HIBC LIC");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(TECHNETIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    strcpy(to_process, "+");
    counter = 41;
    for (i = 0; i < length; i++) {
        counter += posn(TECHNETIUM, source[i]);







|

|

>
|
|





|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
        fclose(f);
    }

    return 0;
}

/* Process health industry bar code data */
static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t length) {
    int counter, error_number, i;
    char to_process[113], temp[2], check_digit;

    /* without "+" and check: max 110 characters in HIBC 2.6 */
    if (length > 110) {
        strcpy(symbol->errtxt, "Data too long for HIBC LIC (B02)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(TECHNETIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (B03)");
        return error_number;
    }

    strcpy(to_process, "+");
    counter = 41;
    for (i = 0; i < length; i++) {
        counter += posn(TECHNETIUM, source[i]);
344
345
346
347
348
349
350



351
352
353
354































355
356
357
358
359
360
361
            break;
        case BARCODE_HIBC_MICPDF:
            error_number = micro_pdf417(symbol, (unsigned char *) to_process, length);
            break;
        case BARCODE_HIBC_AZTEC:
            error_number = aztec(symbol, (unsigned char *) to_process, length);
            break;



    }

    return error_number;
}
































static int gs1_compliant(const int symbology) {
    /* Returns 1 if symbology supports GS1 data */

    int result = 0;

    switch (symbology) {







>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
            break;
        case BARCODE_HIBC_MICPDF:
            error_number = micro_pdf417(symbol, (unsigned char *) to_process, length);
            break;
        case BARCODE_HIBC_AZTEC:
            error_number = aztec(symbol, (unsigned char *) to_process, length);
            break;
        case BARCODE_HIBC_BLOCKF:
            error_number = codablock(symbol, (unsigned char *) to_process, length);
            break;
    }

    return error_number;
}

static void check_row_heights(struct zint_symbol *symbol) {
    /* Check that rows with undefined heights are never less than 5x  */
    int large_bar_count = 0;
    int i;
    int preset_height = 0;
    int large_bar_height = 0;
   
    for (i = 0; i < symbol->rows; i++) {
        preset_height += symbol->row_height[i];
        if (symbol->row_height[i] == 0) {
            large_bar_count++;
        }
    }
    
    if (large_bar_count == 0) {
        symbol->height = preset_height;
    } else {
        large_bar_height = (symbol->height - preset_height) / large_bar_count;
    }
    
    if (large_bar_height < 5) {
        for (i = 0; i < symbol->rows; i++) {
            if (symbol->row_height[i] == 0) {
                symbol->row_height[i] = 5;
                preset_height += 5;
            }
        }
        symbol->height = preset_height;
    }
}

static int gs1_compliant(const int symbology) {
    /* Returns 1 if symbology supports GS1 data */

    int result = 0;

    switch (symbology) {
374
375
376
377
378
379
380

















































381
382
383
384
385
386
387
        case BARCODE_RSS_EXPSTACK_CC:
        case BARCODE_CODE16K:
        case BARCODE_AZTEC:
        case BARCODE_DATAMATRIX:
        case BARCODE_CODEONE:
        case BARCODE_CODE49:
        case BARCODE_QRCODE:

















































            result = 1;
            break;
    }

    return result;
}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
        case BARCODE_RSS_EXPSTACK_CC:
        case BARCODE_CODE16K:
        case BARCODE_AZTEC:
        case BARCODE_DATAMATRIX:
        case BARCODE_CODEONE:
        case BARCODE_CODE49:
        case BARCODE_QRCODE:
        case BARCODE_DOTCODE:
            result = 1;
            break;
    }

    return result;
}

static int is_matrix(const int symbology) {
    /* Returns 1 if symbology is a matrix design */

    int result = 0;

    switch (symbology) {
        case BARCODE_QRCODE:
        case BARCODE_DATAMATRIX:
        case BARCODE_MICROQR:
        case BARCODE_HIBC_DM:
        case BARCODE_AZTEC:
        case BARCODE_HIBC_QR:
        case BARCODE_HIBC_AZTEC:
        case BARCODE_AZRUNE:
        case BARCODE_CODEONE:
        case BARCODE_GRIDMATRIX:
        case BARCODE_HANXIN:
        case BARCODE_DOTCODE:
            result = 1;
            break;
    }

    return result;
}

static int supports_eci(const int symbology) {
    /* Returns 1 if symbology can encode the ECI character */

    int result = 0;

    switch (symbology) {
        case BARCODE_AZTEC:
        case BARCODE_DATAMATRIX:
        case BARCODE_MAXICODE:
        case BARCODE_MICROPDF417:
        case BARCODE_PDF417:
        case BARCODE_PDF417TRUNC:
        case BARCODE_QRCODE:
        case BARCODE_DOTCODE:
        case BARCODE_GRIDMATRIX:
        case BARCODE_HANXIN:
            result = 1;
            break;
    }

    return result;
}

396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416

417

418
419
420
421
422
423
424
        case BARCODE_C25INTER:
        case BARCODE_C25IATA:
        case BARCODE_C25LOGIC:
        case BARCODE_C25IND:
        case BARCODE_CODE39:
        case BARCODE_EXCODE39:
        case BARCODE_EANX:

        case BARCODE_EAN128:
        case BARCODE_CODABAR:
        case BARCODE_CODE128:
        case BARCODE_DPLEIT:
        case BARCODE_DPIDENT:
        case BARCODE_CODE16K:
        case BARCODE_CODE49:
        case BARCODE_CODE93:
        case BARCODE_FLAT:
        case BARCODE_RSS14:
        case BARCODE_RSS_LTD:
        case BARCODE_RSS_EXP:
        case BARCODE_TELEPEN:
        case BARCODE_UPCA:

        case BARCODE_UPCE:

        case BARCODE_POSTNET:
        case BARCODE_MSI_PLESSEY:
        case BARCODE_FIM:
        case BARCODE_LOGMARS:
        case BARCODE_PHARMA:
        case BARCODE_PZN:
        case BARCODE_PHARMA_TWO:







>














>

>







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
        case BARCODE_C25INTER:
        case BARCODE_C25IATA:
        case BARCODE_C25LOGIC:
        case BARCODE_C25IND:
        case BARCODE_CODE39:
        case BARCODE_EXCODE39:
        case BARCODE_EANX:
        case BARCODE_EANX_CHK:
        case BARCODE_EAN128:
        case BARCODE_CODABAR:
        case BARCODE_CODE128:
        case BARCODE_DPLEIT:
        case BARCODE_DPIDENT:
        case BARCODE_CODE16K:
        case BARCODE_CODE49:
        case BARCODE_CODE93:
        case BARCODE_FLAT:
        case BARCODE_RSS14:
        case BARCODE_RSS_LTD:
        case BARCODE_RSS_EXP:
        case BARCODE_TELEPEN:
        case BARCODE_UPCA:
        case BARCODE_UPCA_CHK:
        case BARCODE_UPCE:
        case BARCODE_UPCE_CHK:
        case BARCODE_POSTNET:
        case BARCODE_MSI_PLESSEY:
        case BARCODE_FIM:
        case BARCODE_LOGMARS:
        case BARCODE_PHARMA:
        case BARCODE_PZN:
        case BARCODE_PHARMA_TWO:
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493


494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514

515
516
517

518

519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553


554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575


576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633



634
635
636
637
638
639
640
641
642
643
644
645
646

647
648
649
650
651
652





653
654
655
656
657
658
659
660
661
662
663
664
665
666





667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692




693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715



716

717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
        case BARCODE_HIBC_128:
        case BARCODE_HIBC_39:
        case BARCODE_HIBC_DM:
        case BARCODE_HIBC_QR:
        case BARCODE_HIBC_PDF:
        case BARCODE_HIBC_MICPDF:
        case BARCODE_HIBC_AZTEC:

        case BARCODE_AZRUNE:
        case BARCODE_CODE32:
        case BARCODE_EANX_CC:
        case BARCODE_EAN128_CC:
        case BARCODE_RSS14_CC:
        case BARCODE_RSS_LTD_CC:
        case BARCODE_RSS_EXP_CC:
        case BARCODE_UPCA_CC:
        case BARCODE_UPCE_CC:
        case BARCODE_RSS14STACK_CC:
        case BARCODE_RSS14_OMNI_CC:
        case BARCODE_RSS_EXPSTACK_CC:
        case BARCODE_CHANNEL:
        case BARCODE_CODEONE:
        case BARCODE_GRIDMATRIX:



            result = 1;
            break;
    }

    return result;
}

static int extended_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) {
    int error_number = 0;

    /* These are the "elite" standards which can support multiple character sets */
    switch (symbol->symbology) {
        case BARCODE_QRCODE: error_number = qr_code(symbol, source, length);
            break;
        case BARCODE_MICROQR: error_number = microqr(symbol, source, length);
            break;
        case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length);
            break;


    }

    return error_number;
}

static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, int length) {
    /* These are the "norm" standards which only support Latin-1 at most */
    int error_number = 0;

#ifndef _MSC_VER
    unsigned char preprocessed[length + 1];
#else
    unsigned char* preprocessed = (unsigned char*) _alloca(length + 1);
#endif

    if (symbol->symbology == BARCODE_CODE16K) {
        symbol->whitespace_width = 16;
        symbol->border_width = 2;

        symbol->output_options = BARCODE_BIND;
    }


    if (symbol->symbology == BARCODE_ITF14) {
        symbol->whitespace_width = 20;
        symbol->border_width = 8;

        symbol->output_options = BARCODE_BOX;

    }

    switch (symbol->input_mode) {
        case DATA_MODE:
        case GS1_MODE:
            memcpy(preprocessed, source, length);
            preprocessed[length] = '\0';
            break;
        case UNICODE_MODE:
            error_number = latin1_process(symbol, source, preprocessed, &length);
            if (error_number != 0) {

                return error_number;
            }
            break;
    }

    switch (symbol->symbology) {
        case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, length);
            break;
        case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length);
            break;
        case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length);
            break;
        case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length);
            break;
        case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length);
            break;
        case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length);
            break;
        case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length);
            break;
        case BARCODE_UPCA: error_number = eanx(symbol, preprocessed, length);
            break;
        case BARCODE_UPCE: error_number = eanx(symbol, preprocessed, length);
            break;


        case BARCODE_EANX: error_number = eanx(symbol, preprocessed, length);
            break;
        case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, length);
            break;
        case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length);
            break;
        case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length);
            break;
        case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length);
            break;
        case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length);
            break;
        case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length);
            break;
        case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length);
            break;
        case BARCODE_CODE128: error_number = code_128(symbol, preprocessed, length);
            break;
        case BARCODE_CODE128B: error_number = code_128(symbol, preprocessed, length);
            break;
        case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length);
            break;


        case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length);
            break;
        case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length);
            break;
        case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length);
            break;
        case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length);
            break;
        case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length);
            break;
        case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length);
            break;
        case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length);
            break;
        case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length);
            break;
        case BARCODE_FIM: error_number = fim(symbol, preprocessed, length);
            break;
        case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length);
            break;
        case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length);
            break;
        case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length);
            break;
        case BARCODE_AUSPOST: error_number = australia_post(symbol, preprocessed, length);
            break;
        case BARCODE_AUSREPLY: error_number = australia_post(symbol, preprocessed, length);
            break;
        case BARCODE_AUSROUTE: error_number = australia_post(symbol, preprocessed, length);
            break;

        case BARCODE_AUSREDIRECT: error_number = australia_post(symbol, preprocessed, length);
            break;
        case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length);
            break;
        case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length);
            break;
        case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, length);
            break;
        case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14: error_number = rss14(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14STACK: error_number = rss14(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14STACK_OMNI: error_number = rss14(symbol, preprocessed, length);

            break;
        case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, length);
            break;
        case BARCODE_RSS_EXP: error_number = rssexpanded(symbol, preprocessed, length);
            break;
        case BARCODE_RSS_EXPSTACK: error_number = rssexpanded(symbol, preprocessed, length);
            break;
        case BARCODE_EANX_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_EAN128_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14_CC: error_number = composite(symbol, preprocessed, length);
            break;



        case BARCODE_RSS_LTD_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_RSS_EXP_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_UPCA_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_UPCE_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14STACK_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_RSS14_OMNI_CC: error_number = composite(symbol, preprocessed, length);
            break;
        case BARCODE_RSS_EXPSTACK_CC: error_number = composite(symbol, preprocessed, length);

            break;
        case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length);
            break;
        case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length);
            break;
        case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length);





            break;
        case BARCODE_EAN14: error_number = ean_14(symbol, preprocessed, length);
            break;
        case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length);
            break;
        case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_128: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_39: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_DM: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_QR: error_number = hibc(symbol, preprocessed, length);





            break;
        case BARCODE_HIBC_PDF: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_MICPDF: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_HIBC_AZTEC: error_number = hibc(symbol, preprocessed, length);
            break;
        case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length);
            break;
        case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length);
            break;
        case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length);
            break;
        case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length);
            break;
        case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, length);
            break;
        case BARCODE_PDF417: error_number = pdf417enc(symbol, preprocessed, length);
            break;
        case BARCODE_PDF417TRUNC: error_number = pdf417enc(symbol, preprocessed, length);

            break;
        case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, length);
            break;
        case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, length);
            break;
        case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, length);




            break;
    }

    return error_number;
}

int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) {
    int error_number, error_buffer, i;
#ifdef _MSC_VER
    unsigned char* local_source;
#endif
    error_number = 0;

    if (length == 0) {
        length = ustrlen(source);
    }
    if (length == 0) {
        strcpy(symbol->errtxt, "No input data");
        error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
        return ZINT_ERROR_INVALID_DATA;
    }

    if (strcmp(symbol->outfile, "") == 0) {



        strcpy(symbol->outfile, "out.png");

    }
#ifndef _MSC_VER
    unsigned char local_source[length + 1];
#else
    local_source = (unsigned char*) _alloca(length + 1);
#endif

    /* First check the symbology field */
    if (symbol->symbology < 1) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }

    /* symbol->symbologys 1 to 86 are defined by tbarcode */
    if (symbol->symbology == 5) {
        symbol->symbology = BARCODE_C25MATRIX;
    }
    if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) {
        symbol->symbology = BARCODE_EANX;
    }
    if ((symbol->symbology == 14) || (symbol->symbology == 15)) {
        symbol->symbology = BARCODE_EANX;
    }
    if (symbol->symbology == 17) {
        symbol->symbology = BARCODE_UPCA;
    }
    if (symbol->symbology == 19) {
        strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar");
        symbol->symbology = BARCODE_CODABAR;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 26) {
        symbol->symbology = BARCODE_UPCA;
    }
    if (symbol->symbology == 27) {
        strcpy(symbol->errtxt, "UPCD1 not supported");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }
    if (symbol->symbology == 33) {
        symbol->symbology = BARCODE_EAN128;
    }
    if ((symbol->symbology == 35) || (symbol->symbology == 36)) {
        symbol->symbology = BARCODE_UPCA;
    }
    if ((symbol->symbology == 38) || (symbol->symbology == 39)) {
        symbol->symbology = BARCODE_UPCE;
    }
    if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) {
        symbol->symbology = BARCODE_POSTNET;
    }
    if (symbol->symbology == 46) {
        symbol->symbology = BARCODE_PLESSEY;
    }
    if (symbol->symbology == 48) {
        symbol->symbology = BARCODE_NVE18;
    }
    if (symbol->symbology == 54) {
        strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->symbology == 59) || (symbol->symbology == 61)) {
        symbol->symbology = BARCODE_CODE128;
    }
    if (symbol->symbology == 62) {
        symbol->symbology = BARCODE_CODE93;
    }
    if ((symbol->symbology == 64) || (symbol->symbology == 65)) {
        symbol->symbology = BARCODE_AUSPOST;
    }
    if (symbol->symbology == 73) {
        strcpy(symbol->errtxt, "Codablock E not supported");

        error_number = ZINT_ERROR_INVALID_OPTION;
    }
    if (symbol->symbology == 78) {
        symbol->symbology = BARCODE_RSS14;
    }
    if (symbol->symbology == 83) {
        symbol->symbology = BARCODE_PLANET;
    }
    if (symbol->symbology == 88) {
        symbol->symbology = BARCODE_EAN128;
    }
    if (symbol->symbology == 91) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->symbology >= 94) && (symbol->symbology <= 96)) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 100) {
        symbol->symbology = BARCODE_HIBC_128;
    }
    if (symbol->symbology == 101) {







>















>
>
>


















>
>





|




|

|





>
|
|
|
>
|


>
|
>





|
|


|

>






|

|

|

|

|

|

|

|
|
|
|
>
>
|

|

|

|

|

|

|

|

|
<
|
<
|

>
>
|

|

|

|

|

|

|

|

|

|

|

|

|
<
|
<
|
<
>
|

|

|

|

|

|
<
|
<
|
>

|

|
<
|
<
|
<
<
<
<

>
>
>
|
<
|
<
|
<
|
<
|
<
|
<
|
>

|

|

|
>
>
>
>
>

<
<
<
<
|

|
<
|
<
|
<
|
>
>
>
>
>

|

|

|

<
<
<
<
<
<
|

|

|
<
|
>

|

|

|
>
>
>
>














|


|





>
>
>

>









|











|






|







|





|


|












|













|
>
|











|




|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688

689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718

719

720

721
722
723
724
725
726
727
728
729
730
731
732

733

734
735
736
737
738
739

740

741




742
743
744
745
746

747

748

749

750

751

752
753
754
755
756
757
758
759
760
761
762
763
764
765




766
767
768

769

770

771
772
773
774
775
776
777
778
779
780
781
782
783






784
785
786
787
788

789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
        case BARCODE_HIBC_128:
        case BARCODE_HIBC_39:
        case BARCODE_HIBC_DM:
        case BARCODE_HIBC_QR:
        case BARCODE_HIBC_PDF:
        case BARCODE_HIBC_MICPDF:
        case BARCODE_HIBC_AZTEC:
        case BARCODE_HIBC_BLOCKF:
        case BARCODE_AZRUNE:
        case BARCODE_CODE32:
        case BARCODE_EANX_CC:
        case BARCODE_EAN128_CC:
        case BARCODE_RSS14_CC:
        case BARCODE_RSS_LTD_CC:
        case BARCODE_RSS_EXP_CC:
        case BARCODE_UPCA_CC:
        case BARCODE_UPCE_CC:
        case BARCODE_RSS14STACK_CC:
        case BARCODE_RSS14_OMNI_CC:
        case BARCODE_RSS_EXPSTACK_CC:
        case BARCODE_CHANNEL:
        case BARCODE_CODEONE:
        case BARCODE_GRIDMATRIX:
        case BARCODE_HANXIN:
        case BARCODE_DOTCODE:
        case BARCODE_CODABLOCKF:
            result = 1;
            break;
    }

    return result;
}

static int extended_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) {
    int error_number = 0;

    /* These are the "elite" standards which can support multiple character sets */
    switch (symbol->symbology) {
        case BARCODE_QRCODE: error_number = qr_code(symbol, source, length);
            break;
        case BARCODE_MICROQR: error_number = microqr(symbol, source, length);
            break;
        case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length);
            break;
        case BARCODE_HANXIN: error_number = han_xin(symbol, source, length);
            break;
    }

    return error_number;
}

static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, int in_length) {
    /* These are the "norm" standards which only support Latin-1 at most */
    int error_number = 0;

#ifndef _MSC_VER
    unsigned char preprocessed[in_length + 1];
#else
    unsigned char* preprocessed = (unsigned char*) _alloca(in_length + 1);
#endif

    if (symbol->symbology == BARCODE_CODE16K) {
        symbol->whitespace_width = 16;
        symbol->border_width = 2;
        if (!(symbol->output_options & BARCODE_BIND)) {
            symbol->output_options += BARCODE_BIND;
        }
    }
    else
        if (symbol->symbology == BARCODE_ITF14) {
        symbol->whitespace_width = 20;
        symbol->border_width = 8;
        if (!(symbol->output_options & BARCODE_BOX)) {
            symbol->output_options += BARCODE_BOX;
        }
    }

    switch (symbol->input_mode) {
        case DATA_MODE:
        case GS1_MODE:
            memcpy(preprocessed, source, in_length);
            preprocessed[in_length] = '\0';
            break;
        case UNICODE_MODE:
            error_number = utf_to_eci(symbol->eci, source, preprocessed, &in_length);
            if (error_number != 0) {
                strcpy(symbol->errtxt, "Invalid characters in input data (B04)");
                return error_number;
            }
            break;
    }

    switch (symbol->symbology) {
        case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, in_length);
            break;
        case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, in_length);
            break;
        case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, in_length);
            break;
        case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, in_length);
            break;
        case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, in_length);
            break;
        case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, in_length);
            break;
        case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, in_length);
            break;
        case BARCODE_UPCA: 
        case BARCODE_UPCA_CHK:
        case BARCODE_UPCE: 
        case BARCODE_UPCE_CHK:
        case BARCODE_EANX: 
        case BARCODE_EANX_CHK:
            error_number = eanx(symbol, preprocessed, in_length);
            break;
        case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE39: error_number = c39(symbol, preprocessed, in_length);
            break;
        case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, in_length);
            break;
        case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE93: error_number = c93(symbol, preprocessed, in_length);
            break;
        case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE128:

        case BARCODE_CODE128B: 

            error_number = code_128(symbol, preprocessed, in_length);
            break;
        case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, in_length);
            break;
        case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, in_length);
            break;
        case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, in_length);
            break;
        case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, in_length);
            break;
        case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, in_length);
            break;
        case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, in_length);
            break;
        case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, in_length);
            break;
        case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, in_length);
            break;
        case BARCODE_FIM: error_number = fim(symbol, preprocessed, in_length);
            break;
        case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, in_length);
            break;
        case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, in_length);
            break;
        case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, in_length);
            break;
        case BARCODE_AUSPOST:

        case BARCODE_AUSREPLY: 

        case BARCODE_AUSROUTE:

        case BARCODE_AUSREDIRECT:
            error_number = australia_post(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, in_length);
            break;
        case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, in_length);
            break;
        case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, in_length);
            break;
        case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, in_length);
            break;
        case BARCODE_RSS14:

        case BARCODE_RSS14STACK: 

        case BARCODE_RSS14STACK_OMNI: 
            error_number = rss14(symbol, preprocessed, in_length);
            break;
        case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, in_length);
            break;
        case BARCODE_RSS_EXP: 

        case BARCODE_RSS_EXPSTACK: 

            error_number = rssexpanded(symbol, preprocessed, in_length);




            break;
        case BARCODE_EANX_CC: 
        case BARCODE_EAN128_CC: 
        case BARCODE_RSS14_CC: 
        case BARCODE_RSS_LTD_CC: 

        case BARCODE_RSS_EXP_CC: 

        case BARCODE_UPCA_CC: 

        case BARCODE_UPCE_CC: 

        case BARCODE_RSS14STACK_CC: 

        case BARCODE_RSS14_OMNI_CC: 

        case BARCODE_RSS_EXPSTACK_CC: 
            error_number = composite(symbol, preprocessed, in_length);
            break;
        case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE32: error_number = code32(symbol, preprocessed, in_length);
            break;
        case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, in_length);
            break;
        case BARCODE_EAN14:
            error_number = ean_14(symbol, preprocessed, in_length);
            break;
        case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, in_length);
            break;




        case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, in_length);
            break;
        case BARCODE_HIBC_128: 

        case BARCODE_HIBC_39: 

        case BARCODE_HIBC_DM: 

        case BARCODE_HIBC_QR: 
        case BARCODE_HIBC_PDF: 
        case BARCODE_HIBC_MICPDF: 
        case BARCODE_HIBC_AZTEC: 
        case BARCODE_HIBC_BLOCKF: 
            error_number = hibc(symbol, preprocessed, in_length);
            break;
        case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, in_length);
            break;
        case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, in_length);
            break;






        case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, in_length);
            break;
        case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, in_length);
            break;
        case BARCODE_PDF417: 

        case BARCODE_PDF417TRUNC: 
            error_number = pdf417enc(symbol, preprocessed, in_length);
            break;
        case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, in_length);
            break;
        case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, in_length);
            break;
        case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, in_length);
            break;
        case BARCODE_DOTCODE: error_number = dotcode(symbol, preprocessed, in_length);
            break;
        case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length);
            break;
    }

    return error_number;
}

int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) {
    int error_number, error_buffer, i;
#ifdef _MSC_VER
    unsigned char* local_source;
#endif
    error_number = 0;

    if (length == 0) {
        length = (int) ustrlen(source);
    }
    if (length == 0) {
        strcpy(symbol->errtxt, "No input data (B05)");
        error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
        return ZINT_ERROR_INVALID_DATA;
    }

    if (strcmp(symbol->outfile, "") == 0) {
#ifdef NO_PNG
        strcpy(symbol->outfile, "out.gif");
#else    
        strcpy(symbol->outfile, "out.png");
#endif
    }
#ifndef _MSC_VER
    unsigned char local_source[length + 1];
#else
    local_source = (unsigned char*) _alloca(length + 1);
#endif

    /* First check the symbology field */
    if (symbol->symbology < 1) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B06)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }

    /* symbol->symbologys 1 to 86 are defined by tbarcode */
    if (symbol->symbology == 5) {
        symbol->symbology = BARCODE_C25MATRIX;
    }
    if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) {
        symbol->symbology = BARCODE_EANX;
    }
    if (symbol->symbology == 15) {
        symbol->symbology = BARCODE_EANX;
    }
    if (symbol->symbology == 17) {
        symbol->symbology = BARCODE_UPCA;
    }
    if (symbol->symbology == 19) {
        strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar (B07)");
        symbol->symbology = BARCODE_CODABAR;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 26) {
        symbol->symbology = BARCODE_UPCA;
    }
    if (symbol->symbology == 27) {
        strcpy(symbol->errtxt, "UPCD1 not supported (B08)");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }
    if (symbol->symbology == 33) {
        symbol->symbology = BARCODE_EAN128;
    }
    if (symbol->symbology == 36) {
        symbol->symbology = BARCODE_UPCA;
    }
    if (symbol->symbology == 38) {
        symbol->symbology = BARCODE_UPCE;
    }
    if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) {
        symbol->symbology = BARCODE_POSTNET;
    }
    if (symbol->symbology == 46) {
        symbol->symbology = BARCODE_PLESSEY;
    }
    if (symbol->symbology == 48) {
        symbol->symbology = BARCODE_NVE18;
    }
    if (symbol->symbology == 54) {
        strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128 (B10)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->symbology == 59) || (symbol->symbology == 61)) {
        symbol->symbology = BARCODE_CODE128;
    }
    if (symbol->symbology == 62) {
        symbol->symbology = BARCODE_CODE93;
    }
    if ((symbol->symbology == 64) || (symbol->symbology == 65)) {
        symbol->symbology = BARCODE_AUSPOST;
    }
    if (symbol->symbology == 73) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B11)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 78) {
        symbol->symbology = BARCODE_RSS14;
    }
    if (symbol->symbology == 83) {
        symbol->symbology = BARCODE_PLANET;
    }
    if (symbol->symbology == 88) {
        symbol->symbology = BARCODE_EAN128;
    }
    if (symbol->symbology == 91) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B12)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->symbology >= 94) && (symbol->symbology <= 96)) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B13)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 100) {
        symbol->symbology = BARCODE_HIBC_128;
    }
    if (symbol->symbology == 101) {
825
826
827
828
829
830
831








832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853










854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879





880
881
882
883
884

885
886
887
888
889
890
























891
892
893
894
895
896
897
898
899
900
901
902

903
904
905





906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921







922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937





938












939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956





957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
    }
    if (symbol->symbology == 109) {
        symbol->symbology = BARCODE_HIBC_MICPDF;
    }
    if (symbol->symbology == 111) {
        symbol->symbology = BARCODE_HIBC_BLOCKF;
    }








    if ((symbol->symbology >= 113) && (symbol->symbology <= 127)) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    /* Everything from 128 up is Zint-specific */
    if (symbol->symbology >= 143) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->symbology == BARCODE_CODABLOCKF) || (symbol->symbology == BARCODE_HIBC_BLOCKF)) {
        strcpy(symbol->errtxt, "Codablock F not supported");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }

    if (error_number > 4) {
        error_tag(symbol->errtxt, error_number);
        return error_number;
    } else {
        error_buffer = error_number;
    }











    if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) {
        symbol->input_mode = DATA_MODE;
    }

    if (symbol->input_mode == GS1_MODE) {
        for (i = 0; i < length; i++) {
            if (source[i] == '\0') {
                strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode");
                return ZINT_ERROR_INVALID_DATA;
            }
        }
        if (gs1_compliant(symbol->symbology) == 1) {
            error_number = ugs1_verify(symbol, source, length, local_source);
            if (error_number != 0) {
                return error_number;
            }
            length = ustrlen(local_source);
        } else {
            strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode");
            return ZINT_ERROR_INVALID_OPTION;
        }
    } else {
        memcpy(local_source, source, length);
        local_source[length] = '\0';
    }






    switch (symbol->symbology) {
        case BARCODE_QRCODE:
        case BARCODE_MICROQR:
        case BARCODE_GRIDMATRIX:

            error_number = extended_charset(symbol, local_source, length);
            break;
        default:
            error_number = reduced_charset(symbol, local_source, length);
            break;
    }

























    if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) {
        for (i = 0; i < length; i++) {
            if (local_source[i] == '\0') {
                symbol->text[i] = ' ';
            } else {
                symbol->text[i] = local_source[i];
            }
        }
    }

    if (error_number == 0) {

        error_number = error_buffer;
    }
    error_tag(symbol->errtxt, error_number);





    return error_number;
}

int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) {
    int error_number;
    char output[4];

    switch (rotate_angle) {
        case 0:
        case 90:
        case 180:
        case 270:
            break;
        default:
            strcpy(symbol->errtxt, "Invalid rotation angle");
            return ZINT_ERROR_INVALID_OPTION;







    }

    if (strlen(symbol->outfile) > 3) {
        output[0] = symbol->outfile[strlen(symbol->outfile) - 3];
        output[1] = symbol->outfile[strlen(symbol->outfile) - 2];
        output[2] = symbol->outfile[strlen(symbol->outfile) - 1];
        output[3] = '\0';
        to_upper((unsigned char*) output);

#ifndef NO_PNG
        if (!(strcmp(output, "PNG"))) {
            if (symbol->scale < 1.0) {
                symbol->text[0] = '\0';
            }
            error_number = png_handle(symbol, rotate_angle);
        } else





#endif












            if (!(strcmp(output, "TXT"))) {
            error_number = dump_plot(symbol);
        } else
            if (!(strcmp(output, "EPS"))) {
            error_number = ps_plot(symbol);
        } else
            if (!(strcmp(output, "SVG"))) {
            error_number = svg_plot(symbol);
        } else {
            strcpy(symbol->errtxt, "Unknown output format");
            error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
            return ZINT_ERROR_INVALID_OPTION;
        }
    } else {
        strcpy(symbol->errtxt, "Unknown output format");
        error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
        return ZINT_ERROR_INVALID_OPTION;
    }






    error_tag(symbol->errtxt, error_number);
    return error_number;
}

int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) {
    int error_number;

    switch (rotate_angle) {
        case 0:
        case 90:
        case 180:
        case 270:
            break;
        default:
            strcpy(symbol->errtxt, "Invalid rotation angle");
            return ZINT_ERROR_INVALID_OPTION;
    }

    error_number = bmp_handle(symbol, rotate_angle);
    error_tag(symbol->errtxt, error_number);
    return error_number;
}

int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
    int error_number;

    error_number = 0;

    error_number = ZBarcode_Encode(symbol, input, length);
    if (error_number != 0) {
        return error_number;
    }

    error_number = ZBarcode_Print(symbol, rotate_angle);
    return error_number;
}

int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
    int error_number;

    error_number = 0;

    error_number = ZBarcode_Encode(symbol, input, length);
    if (error_number != 0) {
        return error_number;
    }

    error_number = ZBarcode_Buffer(symbol, rotate_angle);
    return error_number;







>
>
>
>
>
>
>
>
|
|





|



<
<
<
<







>
>
>
>
>
>
>
>
>
>








|










|






>
>
>
>
>





>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>



>
>
>
>
>














|

>
>
>
>
>
>
>









<




|

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>









|




|



>
>
>
>
>















|



|







<
<












<
<







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963




964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100

1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174


1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186


1187
1188
1189
1190
1191
1192
1193
    }
    if (symbol->symbology == 109) {
        symbol->symbology = BARCODE_HIBC_MICPDF;
    }
    if (symbol->symbology == 111) {
        symbol->symbology = BARCODE_HIBC_BLOCKF;
    }
    if ((symbol->symbology == 113) || (symbol->symbology == 114)) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B14)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if (symbol->symbology == 115) {
        symbol->symbology = BARCODE_DOTCODE;
    }
    if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B15)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    /* Everything from 128 up is Zint-specific */
    if (symbol->symbology >= 143) {
        strcpy(symbol->errtxt, "Symbology out of range, using Code 128 (B16)");
        symbol->symbology = BARCODE_CODE128;
        error_number = ZINT_WARN_INVALID_OPTION;
    }





    if (error_number > 4) {
        error_tag(symbol->errtxt, error_number);
        return error_number;
    } else {
        error_buffer = error_number;
    }

    if ((!(supports_eci(symbol->symbology))) && (symbol->eci != 3)) {
        strcpy(symbol->errtxt, "Symbology does not support ECI switching (B17)");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }

    if ((symbol->eci < 3) || (symbol->eci > 26) || (symbol->eci == 14) || (symbol->eci == 19) || (symbol->eci == 25)) {
        strcpy(symbol->errtxt, "Invalid or unsupported ECI mode (B18)");
        error_number = ZINT_ERROR_INVALID_OPTION;
    }

    if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) {
        symbol->input_mode = DATA_MODE;
    }

    if (symbol->input_mode == GS1_MODE) {
        for (i = 0; i < length; i++) {
            if (source[i] == '\0') {
                strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode (B19)");
                return ZINT_ERROR_INVALID_DATA;
            }
        }
        if (gs1_compliant(symbol->symbology) == 1) {
            error_number = ugs1_verify(symbol, source, length, local_source);
            if (error_number != 0) {
                return error_number;
            }
            length = ustrlen(local_source);
        } else {
            strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode (B20)");
            return ZINT_ERROR_INVALID_OPTION;
        }
    } else {
        memcpy(local_source, source, length);
        local_source[length] = '\0';
    }
    
    if ((symbol->dot_size < 0.01) || (symbol->dot_size > 20.0)) {
        strcpy(symbol->errtxt, "Invalid dot size (B21)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    switch (symbol->symbology) {
        case BARCODE_QRCODE:
        case BARCODE_MICROQR:
        case BARCODE_GRIDMATRIX:
        case BARCODE_HANXIN:
            error_number = extended_charset(symbol, local_source, length);
            break;
        default:
            error_number = reduced_charset(symbol, local_source, length);
            break;
    }

    if ((error_number == ZINT_ERROR_INVALID_DATA) && (supports_eci(symbol->symbology)
            && (symbol->input_mode == UNICODE_MODE))) {
        /* Try another ECI mode */
        symbol->eci = get_best_eci(local_source, length);
            
        error_number = ZINT_WARN_USES_ECI;
        strcpy(symbol->errtxt, "Encoded data includes ECI codes (B22)");
        //printf("Data will encode with ECI %d\n", symbol->eci);

        switch (symbol->symbology) {
            case BARCODE_QRCODE:
            case BARCODE_MICROQR:
            case BARCODE_GRIDMATRIX:
            case BARCODE_HANXIN:
                error_number = utf_to_eci(symbol->eci, source, local_source, &length);
                error_number = extended_charset(symbol, local_source, length);
                break;
            default:
                error_number = reduced_charset(symbol, local_source, length);
                break;
        }
        
    }

    if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) {
        for (i = 0; i < length; i++) {
            if (local_source[i] == '\0') {
                symbol->text[i] = ' ';
            } else {
                symbol->text[i] = local_source[i];
            }
        }
    }

    if (error_number == 0) {
        
        error_number = error_buffer;
    }
    error_tag(symbol->errtxt, error_number);
    
    if (error_number <= 5) {
        check_row_heights(symbol);
    }
    
    return error_number;
}

int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) {
    int error_number;
    char output[4];

    switch (rotate_angle) {
        case 0:
        case 90:
        case 180:
        case 270:
            break;
        default:
            strcpy(symbol->errtxt, "Invalid rotation angle (B23)");
            return ZINT_ERROR_INVALID_OPTION;
    }

    if (symbol->output_options & BARCODE_DOTTY_MODE) {
        if (!(is_matrix(symbol->symbology))) {
            strcpy(symbol->errtxt, "Selected symbology cannot be rendered as dots (B24)");
            return ZINT_ERROR_INVALID_OPTION;
        }
    }

    if (strlen(symbol->outfile) > 3) {
        output[0] = symbol->outfile[strlen(symbol->outfile) - 3];
        output[1] = symbol->outfile[strlen(symbol->outfile) - 2];
        output[2] = symbol->outfile[strlen(symbol->outfile) - 1];
        output[3] = '\0';
        to_upper((unsigned char*) output);


        if (!(strcmp(output, "PNG"))) {
            if (symbol->scale < 1.0) {
                symbol->text[0] = '\0';
            }
            error_number = plot_raster(symbol, rotate_angle, OUT_PNG_FILE);
        } else
            if (!(strcmp(output, "BMP"))) {
            if (symbol->scale < 1.0) {
                symbol->text[0] = '\0';
            }
            error_number = plot_raster(symbol, rotate_angle, OUT_BMP_FILE);
        } else
            if (!(strcmp(output, "PCX"))) {
            if (symbol->scale < 1.0) {
                symbol->text[0] = '\0';
            }
            error_number = plot_raster(symbol, rotate_angle, OUT_PCX_FILE);
        } else
            if (!(strcmp(output, "GIF"))) {
            if (symbol->scale < 1.0) {
                symbol->text[0] = '\0';
            }
            error_number = plot_raster(symbol, rotate_angle, OUT_GIF_FILE);
        } else
            if (!(strcmp(output, "TXT"))) {
            error_number = dump_plot(symbol);
        } else
            if (!(strcmp(output, "EPS"))) {
            error_number = ps_plot(symbol);
        } else
            if (!(strcmp(output, "SVG"))) {
            error_number = svg_plot(symbol);
        } else {
            strcpy(symbol->errtxt, "Unknown output format (B25)");
            error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
            return ZINT_ERROR_INVALID_OPTION;
        }
    } else {
        strcpy(symbol->errtxt, "Unknown output format (B26)");
        error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (error_number == ZINT_ERROR_INVALID_OPTION) {
        /* If libpng is not installed */
        strcpy(symbol->errtxt, "Unknown output format (B27)");
    }

    error_tag(symbol->errtxt, error_number);
    return error_number;
}

int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) {
    int error_number;

    switch (rotate_angle) {
        case 0:
        case 90:
        case 180:
        case 270:
            break;
        default:
            strcpy(symbol->errtxt, "Invalid rotation angle (B28)");
            return ZINT_ERROR_INVALID_OPTION;
    }

    error_number = plot_raster(symbol, rotate_angle, OUT_BUFFER);
    error_tag(symbol->errtxt, error_number);
    return error_number;
}

int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
    int error_number;



    error_number = ZBarcode_Encode(symbol, input, length);
    if (error_number != 0) {
        return error_number;
    }

    error_number = ZBarcode_Print(symbol, rotate_angle);
    return error_number;
}

int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
    int error_number;



    error_number = ZBarcode_Encode(symbol, input, length);
    if (error_number != 0) {
        return error_number;
    }

    error_number = ZBarcode_Buffer(symbol, rotate_angle);
    return error_number;
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105

    if (!strcmp(filename, "-")) {
        file = stdin;
        fileLen = 7100;
    } else {
        file = fopen(filename, "rb");
        if (!file) {
            strcpy(symbol->errtxt, "Unable to read input file");
            return ZINT_ERROR_INVALID_DATA;
        }

        /* Get file length */
        fseek(file, 0, SEEK_END);
        fileLen = ftell(file);
        fseek(file, 0, SEEK_SET);

        if (fileLen > 7100) {
            /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */
            strcpy(symbol->errtxt, "Input file too long");
            fclose(file);
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* Allocate memory */
    buffer = (unsigned char *) malloc(fileLen * sizeof (unsigned char));
    if (!buffer) {
        strcpy(symbol->errtxt, "Internal memory error");
        if (strcmp(filename, "-"))
            fclose(file);
        return ZINT_ERROR_MEMORY;
    }

    /* Read file contents into buffer */

    do {
        n = fread(buffer + nRead, 1, fileLen - nRead, file);
        if (ferror(file)) {
            strcpy(symbol->errtxt, strerror(errno));
            nRead = 0;
            return ZINT_ERROR_INVALID_DATA;
        }
        nRead += n;
    } while (!feof(file) && (0 < n) && (nRead < fileLen));

    fclose(file);
    ret = ZBarcode_Encode(symbol, buffer, nRead);
    free(buffer);
    return ret;
}

int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) {
    int error_number;

    error_number = 0;

    error_number = ZBarcode_Encode_File(symbol, filename);
    if (error_number != 0) {
        return error_number;
    }

    return ZBarcode_Print(symbol, rotate_angle);
}

int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) {
    int error_number;

    error_number = 0;

    error_number = ZBarcode_Encode_File(symbol, filename);
    if (error_number != 0) {
        return error_number;
    }

    return ZBarcode_Buffer(symbol, rotate_angle);
}

/*
 * Rendering support, initially added by Sam Lown.
 *
 * Converts encoded data into an intermediate format to be interpreted
 * in other applications using this library.
 *
 * If the width and height are not set to zero, the barcode will be resized to those
 * dimensions. The symbol->scale and symbol->height values are totally ignored in this case.
 *
 */
int ZBarcode_Render(struct zint_symbol *symbol, float width, float height) {
    // Send the request to the render_plot method
    return render_plot(symbol, width, height);
}







|










|








|











<














<
<











<
<


















|



1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254


1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265


1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287

    if (!strcmp(filename, "-")) {
        file = stdin;
        fileLen = 7100;
    } else {
        file = fopen(filename, "rb");
        if (!file) {
            strcpy(symbol->errtxt, "Unable to read input file (B29)");
            return ZINT_ERROR_INVALID_DATA;
        }

        /* Get file length */
        fseek(file, 0, SEEK_END);
        fileLen = ftell(file);
        fseek(file, 0, SEEK_SET);

        if (fileLen > 7100) {
            /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */
            strcpy(symbol->errtxt, "Input file too long (B30)");
            fclose(file);
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* Allocate memory */
    buffer = (unsigned char *) malloc(fileLen * sizeof (unsigned char));
    if (!buffer) {
        strcpy(symbol->errtxt, "Internal memory error (B31)");
        if (strcmp(filename, "-"))
            fclose(file);
        return ZINT_ERROR_MEMORY;
    }

    /* Read file contents into buffer */

    do {
        n = fread(buffer + nRead, 1, fileLen - nRead, file);
        if (ferror(file)) {
            strcpy(symbol->errtxt, strerror(errno));

            return ZINT_ERROR_INVALID_DATA;
        }
        nRead += n;
    } while (!feof(file) && (0 < n) && (nRead < fileLen));

    fclose(file);
    ret = ZBarcode_Encode(symbol, buffer, nRead);
    free(buffer);
    return ret;
}

int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) {
    int error_number;



    error_number = ZBarcode_Encode_File(symbol, filename);
    if (error_number != 0) {
        return error_number;
    }

    return ZBarcode_Print(symbol, rotate_angle);
}

int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) {
    int error_number;



    error_number = ZBarcode_Encode_File(symbol, filename);
    if (error_number != 0) {
        return error_number;
    }

    return ZBarcode_Buffer(symbol, rotate_angle);
}

/*
 * Rendering support, initially added by Sam Lown.
 *
 * Converts encoded data into an intermediate format to be interpreted
 * in other applications using this library.
 *
 * If the width and height are not set to zero, the barcode will be resized to those
 * dimensions. The symbol->scale and symbol->height values are totally ignored in this case.
 *
 */
int ZBarcode_Render(struct zint_symbol *symbol, const float width, const float height) {
    // Send the request to the render_plot method
    return render_plot(symbol, width, height);
}
Changes to jni/zint/backend/maxicode.c.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/* Includes corrections thanks to Monica Swanson @ Source Technologies */

#include "common.h"
#include "maxicode.h"
#include "reedsol.h"
#include <string.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif

int maxi_codeword[144];

/* Handles error correction of primary message */
void maxi_do_primary_check() {
    unsigned char data[15];
    unsigned char results[15];







<
<
<
<
<







33
34
35
36
37
38
39





40
41
42
43
44
45
46
/* Includes corrections thanks to Monica Swanson @ Source Technologies */

#include "common.h"
#include "maxicode.h"
#include "reedsol.h"
#include <string.h>
#include <stdlib.h>






int maxi_codeword[144];

/* Handles error correction of primary message */
void maxi_do_primary_check() {
    unsigned char data[15];
    unsigned char results[15];
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    for (i = 143; i > bump_posn; i--) {
        set[i] = set[i - 1];
        character[i] = character[i - 1];
    }
}

/* Format text according to Appendix A */
int maxi_text_process(int mode, unsigned char source[], int length) {
    /* This code doesn't make use of [Lock in C], [Lock in D]
    and [Lock in E] and so is not always the most efficient at
    compressing data, but should suffice for most applications */

    int set[144], character[144], i, j, done, count, current_set;

    if (length > 138) {







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    for (i = 143; i > bump_posn; i--) {
        set[i] = set[i - 1];
        character[i] = character[i - 1];
    }
}

/* Format text according to Appendix A */
int maxi_text_process(int mode, unsigned char source[], int length, int eci) {
    /* This code doesn't make use of [Lock in C], [Lock in D]
    and [Lock in E] and so is not always the most efficient at
    compressing data, but should suffice for most applications */

    int set[144], character[144], i, j, done, count, current_set;

    if (length > 138) {
452
453
454
455
456
457
458









459
460
461
462
463
464
465
            }
            length -= 3;
        } else {
            i++;
        }
    } while (i <= 143);










    if (((mode == 2) || (mode == 3)) && (length > 84)) {
        return ZINT_ERROR_TOO_LONG;
    }

    if (((mode == 4) || (mode == 6)) && (length > 93)) {
        return ZINT_ERROR_TOO_LONG;
    }







>
>
>
>
>
>
>
>
>







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
            }
            length -= 3;
        } else {
            i++;
        }
    } while (i <= 143);

    /* Insert ECI at the beginning of message if needed */
    if (eci != 3) {
        maxi_bump(set, character, 0);
        character[0] = 27; // ECI
        maxi_bump(set, character, 1);
        character[1] = eci;
        length += 2;
    }
    
    if (((mode == 2) || (mode == 3)) && (length > 84)) {
        return ZINT_ERROR_TOO_LONG;
    }

    if (((mode == 4) || (mode == 6)) && (length > 93)) {
        return ZINT_ERROR_TOO_LONG;
    }
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
    maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2);
    maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4);
    maxi_codeword[7] = (country & 0xfc) >> 2;
    maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2);
    maxi_codeword[9] = ((service & 0x3f0) >> 4);
}

int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) {
    int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0;
    int bit_pattern[7], internal_error = 0, eclen, error_number;
    char postcode[12], countrystr[4], servicestr[4];

#ifndef _MSC_VER
    unsigned char local_source[length + 1];
#else
    unsigned char* local_source = (unsigned char*) _alloca(length + 1);
#endif

    mode = symbol->option_1;
    strcpy(postcode, "");
    strcpy(countrystr, "");
    strcpy(servicestr, "");

    /* The following to be replaced by ECI handling */
    switch (symbol->input_mode) {
        case DATA_MODE:
        case GS1_MODE:
            memcpy(local_source, source, length);
            local_source[length] = '\0';
            break;
        case UNICODE_MODE:
            error_number = latin1_process(symbol, source, local_source, &length);
            if (error_number != 0) {
                return error_number;
            }
            break;
    }
    memset(maxi_codeword, 0, sizeof (maxi_codeword));

    if (mode == -1) { /* If mode is unspecified */
        lp = strlen(symbol->primary);
        if (lp == 0) {
            mode = 4;
        } else {
            mode = 2;
            for (i = 0; i < 10 && i < lp; i++) {
                if ((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) {
                    mode = 3;
                    break;
                }
            }
        }
    }

    if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */
        strcpy(symbol->errtxt, "Invalid Maxicode Mode");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
        if (lp == 0) { /* Mode set manually means lp doesn't get set */
            lp = strlen(symbol->primary);
        }
        if (lp != 15) {
            strcpy(symbol->errtxt, "Invalid Primary String");
            return ZINT_ERROR_INVALID_DATA;
        }

        for (i = 9; i < 15; i++) { /* check that country code and service are numeric */
            if ((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) {
                strcpy(symbol->errtxt, "Invalid Primary String");
                return ZINT_ERROR_INVALID_DATA;
            }
        }

        memcpy(postcode, symbol->primary, 9);
        postcode[9] = '\0';








|

|


<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<


















|








|





|







553
554
555
556
557
558
559
560
561
562
563
564






565
566
567
568
569














570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
    maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2);
    maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4);
    maxi_codeword[7] = (country & 0xfc) >> 2;
    maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2);
    maxi_codeword[9] = ((service & 0x3f0) >> 4);
}

int maxicode(struct zint_symbol *symbol, unsigned char local_source[], int length) {
    int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0;
    int bit_pattern[7], internal_error = 0, eclen;
    char postcode[12], countrystr[4], servicestr[4];







    mode = symbol->option_1;
    strcpy(postcode, "");
    strcpy(countrystr, "");
    strcpy(servicestr, "");















    memset(maxi_codeword, 0, sizeof (maxi_codeword));

    if (mode == -1) { /* If mode is unspecified */
        lp = strlen(symbol->primary);
        if (lp == 0) {
            mode = 4;
        } else {
            mode = 2;
            for (i = 0; i < 10 && i < lp; i++) {
                if ((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) {
                    mode = 3;
                    break;
                }
            }
        }
    }

    if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */
        strcpy(symbol->errtxt, "Invalid Maxicode Mode (E50)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
        if (lp == 0) { /* Mode set manually means lp doesn't get set */
            lp = strlen(symbol->primary);
        }
        if (lp != 15) {
            strcpy(symbol->errtxt, "Invalid Primary String (E51)");
            return ZINT_ERROR_INVALID_DATA;
        }

        for (i = 9; i < 15; i++) { /* check that country code and service are numeric */
            if ((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) {
                strcpy(symbol->errtxt, "Invalid Primary String (E52)");
                return ZINT_ERROR_INVALID_DATA;
            }
        }

        memcpy(postcode, symbol->primary, 9);
        postcode[9] = '\0';

653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
        if (mode == 3) {
            maxi_do_primary_3(postcode, countrycode, service);
        }
    } else {
        maxi_codeword[0] = mode;
    }

    i = maxi_text_process(mode, local_source, length);
    if (i == ZINT_ERROR_TOO_LONG) {
        strcpy(symbol->errtxt, "Input data too long");
        return i;
    }

    /* All the data is sorted - now do error correction */
    maxi_do_primary_check(); /* always EEC */

    if (mode == 5)







|

|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
        if (mode == 3) {
            maxi_do_primary_3(postcode, countrycode, service);
        }
    } else {
        maxi_codeword[0] = mode;
    }

    i = maxi_text_process(mode, local_source, length, symbol->eci);
    if (i == ZINT_ERROR_TOO_LONG) {
        strcpy(symbol->errtxt, "Input data too long (E53)");
        return i;
    }

    /* All the data is sorted - now do error correction */
    maxi_do_primary_check(); /* always EEC */

    if (mode == 5)
Deleted jni/zint/backend/maxipng.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* maxipng.h - Shapes for Maxicode output to PNG file */

/*
    libzint - the open source barcode library
    Copyright (C) 2008-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

/* This file contains the pixel-by-pixel representation of maxicode glyphs
   at a resolution of 12 pixels per millimeter. hexagon[] is taken directly
   from ISO 16023 Annex J. bullseye[] was calculated by the Gimp */

#define SSET	"0123456789ABCDEF"

static const int hexagon[120] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
    0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
    0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
    0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

static const unsigned int bullseye_compressed[] = {
    0, 0, 0, 0, 0, 255, 248, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 31, 255, 255, 192, 0, 0, 0, 0,
    0, 0, 0, 1, 255, 255, 255, 252, 0, 0, 0, 0,
    0, 0, 0, 7, 255, 255, 255, 255, 0, 0, 0, 0,
    0, 0, 0, 31, 255, 255, 255, 255, 192, 0, 0, 0,
    0, 0, 0, 127, 255, 255, 255, 255, 240, 0, 0, 0,
    0, 0, 1, 255, 255, 255, 255, 255, 252, 0, 0, 0,
    0, 0, 7, 255, 255, 255, 255, 255, 255, 0, 0, 0,
    0, 0, 15, 255, 255, 0, 7, 255, 255, 128, 0, 0,
    0, 0, 63, 255, 240, 0, 0, 127, 255, 224, 0, 0,
    0, 0, 127, 255, 128, 0, 0, 15, 255, 240, 0, 0,
    0, 0, 255, 252, 0, 0, 0, 1, 255, 248, 0, 0,
    0, 1, 255, 240, 0, 0, 0, 0, 127, 252, 0, 0,
    0, 3, 255, 224, 0, 0, 0, 0, 63, 254, 0, 0,
    0, 7, 255, 128, 0, 0, 0, 0, 15, 255, 0, 0,
    0, 15, 255, 0, 0, 0, 0, 0, 7, 255, 128, 0,
    0, 31, 252, 0, 0, 127, 240, 0, 1, 255, 192, 0,
    0, 63, 248, 0, 7, 255, 255, 0, 0, 255, 224, 0,
    0, 127, 240, 0, 63, 255, 255, 224, 0, 127, 240, 0,
    0, 127, 224, 0, 255, 255, 255, 248, 0, 63, 240, 0,
    0, 255, 192, 1, 255, 255, 255, 252, 0, 31, 248, 0,
    1, 255, 128, 7, 255, 255, 255, 255, 0, 15, 252, 0,
    1, 255, 0, 15, 255, 255, 255, 255, 128, 7, 252, 0,
    3, 255, 0, 63, 255, 255, 255, 255, 224, 7, 254, 0,
    3, 254, 0, 127, 255, 192, 31, 255, 240, 3, 254, 0,
    7, 252, 0, 255, 252, 0, 1, 255, 248, 1, 255, 0,
    7, 252, 1, 255, 240, 0, 0, 127, 252, 1, 255, 0,
    15, 248, 1, 255, 192, 0, 0, 31, 252, 0, 255, 128,
    15, 240, 3, 255, 128, 0, 0, 15, 254, 0, 127, 128,
    31, 240, 7, 255, 0, 0, 0, 7, 255, 0, 127, 192,
    31, 224, 7, 254, 0, 0, 0, 3, 255, 0, 63, 192,
    63, 224, 15, 252, 0, 0, 0, 1, 255, 128, 63, 224,
    63, 224, 31, 248, 0, 63, 192, 0, 255, 192, 63, 224,
    63, 192, 31, 240, 0, 255, 240, 0, 127, 192, 31, 224,
    63, 192, 63, 224, 3, 255, 252, 0, 63, 224, 31, 224,
    127, 192, 63, 224, 7, 255, 254, 0, 63, 224, 31, 240,
    127, 128, 63, 192, 15, 255, 255, 0, 31, 224, 15, 240,
    127, 128, 127, 192, 31, 255, 255, 128, 31, 240, 15, 240,
    127, 128, 127, 128, 63, 255, 255, 192, 15, 240, 15, 240,
    127, 128, 127, 128, 63, 255, 255, 192, 15, 240, 15, 240,
    255, 0, 127, 128, 127, 240, 255, 224, 15, 240, 7, 240,
    255, 0, 255, 128, 127, 192, 63, 224, 15, 248, 7, 240,
    255, 0, 255, 0, 255, 128, 31, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 128, 31, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 0, 15, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 0, 15, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 0, 15, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 0, 15, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 128, 31, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 255, 128, 31, 240, 7, 248, 7, 240,
    255, 0, 255, 0, 127, 192, 63, 224, 7, 248, 7, 240,
    255, 0, 255, 128, 127, 240, 255, 224, 15, 248, 7, 240,
    255, 0, 127, 128, 63, 255, 255, 192, 15, 240, 7, 240,
    127, 128, 127, 128, 63, 255, 255, 192, 15, 240, 15, 240,
    127, 128, 127, 128, 31, 255, 255, 128, 15, 240, 15, 240,
    127, 128, 127, 192, 15, 255, 255, 0, 31, 240, 15, 240,
    127, 128, 63, 192, 7, 255, 254, 0, 31, 224, 15, 240,
    127, 192, 63, 224, 3, 255, 252, 0, 63, 224, 31, 240,
    63, 192, 63, 224, 0, 255, 240, 0, 63, 224, 31, 224,
    63, 192, 31, 240, 0, 63, 192, 0, 127, 192, 31, 224,
    63, 224, 31, 248, 0, 0, 0, 0, 255, 192, 63, 224,
    63, 224, 15, 252, 0, 0, 0, 1, 255, 128, 63, 224,
    31, 224, 7, 254, 0, 0, 0, 3, 255, 0, 63, 192,
    31, 240, 7, 255, 0, 0, 0, 7, 255, 0, 127, 192,
    15, 240, 3, 255, 128, 0, 0, 15, 254, 0, 127, 128,
    15, 248, 1, 255, 192, 0, 0, 31, 252, 0, 255, 128,
    7, 252, 1, 255, 240, 0, 0, 127, 252, 1, 255, 0,
    7, 252, 0, 255, 252, 0, 1, 255, 248, 1, 255, 0,
    3, 254, 0, 127, 255, 192, 31, 255, 240, 3, 254, 0,
    3, 255, 0, 63, 255, 255, 255, 255, 224, 7, 254, 0,
    1, 255, 0, 15, 255, 255, 255, 255, 128, 7, 252, 0,
    1, 255, 128, 7, 255, 255, 255, 255, 0, 15, 252, 0,
    0, 255, 192, 1, 255, 255, 255, 252, 0, 31, 248, 0,
    0, 127, 224, 0, 255, 255, 255, 248, 0, 63, 240, 0,
    0, 127, 240, 0, 63, 255, 255, 224, 0, 127, 240, 0,
    0, 63, 248, 0, 7, 255, 255, 0, 0, 255, 224, 0,
    0, 31, 252, 0, 0, 127, 240, 0, 1, 255, 192, 0,
    0, 15, 255, 0, 0, 0, 0, 0, 7, 255, 128, 0,
    0, 7, 255, 128, 0, 0, 0, 0, 15, 255, 0, 0,
    0, 3, 255, 224, 0, 0, 0, 0, 63, 254, 0, 0,
    0, 1, 255, 240, 0, 0, 0, 0, 127, 252, 0, 0,
    0, 0, 255, 252, 0, 0, 0, 1, 255, 248, 0, 0,
    0, 0, 127, 255, 128, 0, 0, 15, 255, 240, 0, 0,
    0, 0, 63, 255, 240, 0, 0, 127, 255, 224, 0, 0,
    0, 0, 15, 255, 255, 0, 7, 255, 255, 128, 0, 0,
    0, 0, 7, 255, 255, 255, 255, 255, 255, 0, 0, 0,
    0, 0, 1, 255, 255, 255, 255, 255, 252, 0, 0, 0,
    0, 0, 0, 127, 255, 255, 255, 255, 240, 0, 0, 0,
    0, 0, 0, 31, 255, 255, 255, 255, 192, 0, 0, 0,
    0, 0, 0, 7, 255, 255, 255, 255, 0, 0, 0, 0,
    0, 0, 0, 1, 255, 255, 255, 252, 0, 0, 0, 0,
    0, 0, 0, 0, 31, 255, 255, 192, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 255, 248, 0, 0, 0, 0, 0
};

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































Changes to jni/zint/backend/medical.c.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"

extern int c39(struct zint_symbol *symbol, unsigned char source[], int length);
/* Codabar table checked against EN 798:1995 */

#define CALCIUM	"0123456789-$:/.+ABCD"

static const char *CodaTable[20] = {
    "11111221", "11112211", "11121121", "22111111", "11211211", "21111211",
    "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121",







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"

extern int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length);
/* Codabar table checked against EN 798:1995 */

#define CALCIUM	"0123456789-$:/.+ABCD"

static const char *CodaTable[20] = {
    "11111221", "11112211", "11121121", "22111111", "11211211", "21111211",
    "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121",
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
       the specification at http://www.laetus.com/laetus.php?request=file&id=69 */

    unsigned long int tester;
    int counter, error_number, h;
    char inter[18] = {0}; /* 131070 -> 17 bits */
    char dest[64]; /* 17 * 2 + 1 */

    error_number = 0;

    if (length > 6) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    tester = atoi((char*) source);

    if ((tester < 3) || (tester > 131070)) {
        strcpy(symbol->errtxt, "Data out of range");
        return ZINT_ERROR_INVALID_DATA;
    }

    do {
        if (!(tester & 1)) {
            strcat(inter, "W");
            tester = (tester - 2) / 2;







<
<

|




|






|







60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
       the specification at http://www.laetus.com/laetus.php?request=file&id=69 */

    unsigned long int tester;
    int counter, error_number, h;
    char inter[18] = {0}; /* 131070 -> 17 bits */
    char dest[64]; /* 17 * 2 + 1 */



    if (length > 6) {
        strcpy(symbol->errtxt, "Input too long (C50)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C51)");
        return error_number;
    }

    tester = atoi((char*) source);

    if ((tester < 3) || (tester > 131070)) {
        strcpy(symbol->errtxt, "Data out of range (C52)");
        return ZINT_ERROR_INVALID_DATA;
    }

    do {
        if (!(tester & 1)) {
            strcat(inter, "W");
            tester = (tester - 2) / 2;
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    int counter, h;
    char inter[17];
    int error_number;

    tester = atoi((char*) source);

    if ((tester < 4) || (tester > 64570080)) {
        strcpy(symbol->errtxt, "Data out of range");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = 0;
    strcpy(inter, "");
    do {
        switch (tester % 3) {
            case 0:







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    int counter, h;
    char inter[17];
    int error_number;

    tester = atoi((char*) source);

    if ((tester < 4) || (tester > 64570080)) {
        strcpy(symbol->errtxt, "Data out of range (C53)");
        return ZINT_ERROR_INVALID_DATA;
    }
    error_number = 0;
    strcpy(inter, "");
    do {
        switch (tester % 3) {
            case 0:
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    char height_pattern[200];
    unsigned int loopey, h;
    int writer;
    int error_number = 0;
    strcpy(height_pattern, "");

    if (length > 8) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    error_number = pharma_two_calc(symbol, source, height_pattern);
    if (error_number != 0) {
        return error_number;
    }








|




|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    char height_pattern[200];
    unsigned int loopey, h;
    int writer;
    int error_number = 0;
    strcpy(height_pattern, "");

    if (length > 8) {
        strcpy(symbol->errtxt, "Input too long (C54)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C55)");
        return error_number;
    }
    error_number = pharma_two_calc(symbol, source, height_pattern);
    if (error_number != 0) {
        return error_number;
    }

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

/* The Codabar system consisting of simple substitution */
int codabar(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number;
    char dest[512];

    error_number = 0;
    strcpy(dest, "");

    if (length > 60) { /* No stack smashing please */
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(CALCIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    /* Codabar must begin and end with the characters A, B, C or D */
    if ((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C')
            && (source[0] != 'D')) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return ZINT_ERROR_INVALID_DATA;
    }

    if ((source[length - 1] != 'A') && (source[length - 1] != 'B') &&
            (source[length - 1] != 'C') && (source[length - 1] != 'D')) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < length; i++) {
        lookup(CALCIUM, CodaTable, source[i], dest);
    }








<



|





|





|





|







193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

/* The Codabar system consisting of simple substitution */
int codabar(struct zint_symbol *symbol, unsigned char source[], int length) {

    int i, error_number;
    char dest[512];


    strcpy(dest, "");

    if (length > 60) { /* No stack smashing please */
        strcpy(symbol->errtxt, "Input too long (C56)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(CALCIUM, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C57)");
        return error_number;
    }
    /* Codabar must begin and end with the characters A, B, C or D */
    if ((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C')
            && (source[0] != 'D')) {
        strcpy(symbol->errtxt, "Invalid characters in data (C58)");
        return ZINT_ERROR_INVALID_DATA;
    }

    if ((source[length - 1] != 'A') && (source[length - 1] != 'B') &&
            (source[length - 1] != 'C') && (source[length - 1] != 'D')) {
        strcpy(symbol->errtxt, "Invalid characters in data (C59)");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < length; i++) {
        lookup(CALCIUM, CodaTable, source[i], dest);
    }

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    char localstr[10], risultante[7];
    long int pharmacode, remainder, devisor;
    int codeword[6];
    char tabella[34];

    /* Validate the input */
    if (length > 8) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* Add leading zeros as required */
    zeroes = 8 - length;
    memset(localstr, '0', zeroes);
    strcpy(localstr + zeroes, (char*) source);







|




|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    char localstr[10], risultante[7];
    long int pharmacode, remainder, devisor;
    int codeword[6];
    char tabella[34];

    /* Validate the input */
    if (length > 8) {
        strcpy(symbol->errtxt, "Input too long (C5A)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C5B)");
        return error_number;
    }

    /* Add leading zeros as required */
    zeroes = 8 - length;
    memset(localstr, '0', zeroes);
    strcpy(localstr + zeroes, (char*) source);
Added jni/zint/backend/pcx.c.
























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* pcx.c - Handles output to ZSoft PCX file */

/*
    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "pcx.h"        /* PCX header structure */
#include <math.h>
#ifdef _MSC_VER
#include <io.h>
#include <fcntl.h>
#include <malloc.h>
#endif

#define SSET	"0123456789ABCDEF"

int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
    int row, column, i, colour;
    int run_count;
    FILE *pcx_file;
    pcx_header_t header;
#ifdef _MSC_VER
    unsigned char* rle_row;
#endif

#ifndef _MSC_VER
    unsigned char rle_row[symbol->bitmap_width];
#else
    rle_row = (unsigned char *) _alloca((symbol->bitmap_width * 6) * sizeof (unsigned char));
#endif /* _MSC_VER */

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);


    header.manufacturer = 10; // ZSoft
    header.version = 5; // Version 3.0
    header.encoding = 1; // Run length encoding
    header.bits_per_pixel = 8;
    header.window_xmin = 0;
    header.window_ymin = 0;
    header.window_xmax = symbol->bitmap_width - 1;
    header.window_ymax = symbol->bitmap_height - 1;
    header.horiz_dpi = 300;
    header.vert_dpi = 300;

    for (i = 0; i < 48; i++) {
        header.colourmap[i] = 0x00;
    }

    header.reserved = 0;
    header.number_of_planes = 3;

    if (symbol->bitmap_width % 2) {
        header.bytes_per_line = symbol->bitmap_width + 1;
    } else {
        header.bytes_per_line = symbol->bitmap_width;
    }

    header.palette_info = 1; // Colour
    header.horiz_screen_size = 0;
    header.vert_screen_size = 0;

    for (i = 0; i < 54; i++) {
        header.filler[i] = 0x00;
    }

    /* Open output file in binary mode */
    if (symbol->output_options & BARCODE_STDOUT) {
#ifdef _MSC_VER
        if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
#endif
        pcx_file = stdout;
    } else {
        if (!(pcx_file = fopen(symbol->outfile, "wb"))) {
            strcpy(symbol->errtxt, "Can't open output file (F20)");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    fwrite(&header, sizeof (pcx_header_t), 1, pcx_file);

    for (row = 0; row < symbol->bitmap_height; row++) {
        for (colour = 0; colour < 3; colour++) {
            for (column = 0; column < symbol->bitmap_width; column++) {
                switch (colour) {
                    case 0:
                        if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') {
                            rle_row[column] = fgred;
                        } else {
                            rle_row[column] = bgred;
                        }
                        break;
                    case 1:
                        if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') {
                            rle_row[column] = fggrn;
                        } else {
                            rle_row[column] = bggrn;
                        }
                        break;
                    case 2:
                        if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') {
                            rle_row[column] = fgblu;
                        } else {
                            rle_row[column] = bgblu;
                        }
                        break;
                }
            }

            run_count = 1;
            for (column = 1; column < symbol->bitmap_width; column++) {
                if ((rle_row[column - 1] == rle_row[column]) && (run_count < 63)) {
                    run_count++;
                } else {
                    run_count += 0xc0;
                    fputc(run_count, pcx_file);
                    fputc(rle_row[column - 1], pcx_file);
                    run_count = 1;
                }
            }

            if (run_count > 1) {
                run_count += 0xc0;
                fputc(run_count, pcx_file);
                fputc(rle_row[column - 1], pcx_file);
            }
        }
    }

    fclose(pcx_file);

    return 0;
}
Added jni/zint/backend/pcx.h.
























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*  pcx.h - header structure for ZSoft PCX files

    libzint - the open source barcode library
    Copyright (C) 2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#ifndef PCX_H
#define PCX_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#include <windows.h>
#include "stdint_msvc.h"
#else
#include <stdint.h>
#endif

#pragma pack (1)
    
    typedef struct pcx_header {
        uint8_t manufacturer;
        uint8_t version;
        uint8_t encoding;
        uint8_t bits_per_pixel;
        uint16_t window_xmin;
        uint16_t window_ymin;
        uint16_t window_xmax;
        uint16_t window_ymax;
        uint16_t horiz_dpi;
        uint16_t vert_dpi;
        uint8_t colourmap[48];
        uint8_t reserved;
        uint8_t number_of_planes;
        uint16_t bytes_per_line;
        uint16_t palette_info;
        uint16_t horiz_screen_size;
        uint16_t vert_screen_size;
        uint8_t filler[54];
    } pcx_header_t;

#pragma pack ()
    
#ifdef __cplusplus
}
#endif

#endif /* PCX_H */

Changes to jni/zint/backend/pdf417.c.
605
606
607
608
609
610
611

612
613
614
615








616
617
618
619
620
621
622
            }
        }
    }

    /* 541 - now compress the data */
    indexchaine = 0;
    mclength = 0;

    if (symbol->output_options & READER_INIT) {
        chainemc[mclength] = 921; /* Reader Initialisation */
        mclength++;
    }








    for (i = 0; i < indexliste; i++) {
        switch (liste[1][i]) {
            case TEX: /* 547 - text mode */
                textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
            case BYT: /* 670 - octet stream mode */
                byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i);







>




>
>
>
>
>
>
>
>







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
            }
        }
    }

    /* 541 - now compress the data */
    indexchaine = 0;
    mclength = 0;
    
    if (symbol->output_options & READER_INIT) {
        chainemc[mclength] = 921; /* Reader Initialisation */
        mclength++;
    }
    
    if (symbol->eci != 3) {
        chainemc[mclength] = 927; /* ECI */
        mclength++;
        chainemc[mclength] = symbol->eci;
        mclength++;
    }
    
    for (i = 0; i < indexliste; i++) {
        switch (liste[1][i]) {
            case TEX: /* 547 - text mode */
                textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
            case BYT: /* 670 - octet stream mode */
                byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i);
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
/* 345 */
int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length) {
    int codeerr, error_number;

    error_number = 0;

    if ((symbol->option_1 < -1) || (symbol->option_1 > 8)) {
        strcpy(symbol->errtxt, "Security value out of range");
        symbol->option_1 = -1;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->option_2 < 0) || (symbol->option_2 > 30)) {
        strcpy(symbol->errtxt, "Number of columns out of range");
        symbol->option_2 = 0;
        error_number = ZINT_WARN_INVALID_OPTION;
    }

    /* 349 */
    codeerr = pdf417(symbol, source, length);

    /* 352 */
    if (codeerr != 0) {
        switch (codeerr) {
            case 1:
                strcpy(symbol->errtxt, "No such file or file unreadable");
                error_number = ZINT_ERROR_INVALID_OPTION;
                break;
            case 2:
                strcpy(symbol->errtxt, "Input string too long");
                error_number = ZINT_ERROR_TOO_LONG;
                break;
            case 3:
                strcpy(symbol->errtxt, "Number of codewords per row too small");
                error_number = ZINT_WARN_INVALID_OPTION;
                break;
            case 4:
                strcpy(symbol->errtxt, "Data too long for specified number of columns");
                error_number = ZINT_ERROR_TOO_LONG;
                break;
            default:
                strcpy(symbol->errtxt, "Something strange happened");
                error_number = ZINT_ERROR_ENCODING_PROBLEM;
                break;
        }
    }

    /* 364 */
    return error_number;







|




|











|



|



|



|



|







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
/* 345 */
int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length) {
    int codeerr, error_number;

    error_number = 0;

    if ((symbol->option_1 < -1) || (symbol->option_1 > 8)) {
        strcpy(symbol->errtxt, "Security value out of range (D60)");
        symbol->option_1 = -1;
        error_number = ZINT_WARN_INVALID_OPTION;
    }
    if ((symbol->option_2 < 0) || (symbol->option_2 > 30)) {
        strcpy(symbol->errtxt, "Number of columns out of range (D61)");
        symbol->option_2 = 0;
        error_number = ZINT_WARN_INVALID_OPTION;
    }

    /* 349 */
    codeerr = pdf417(symbol, source, length);

    /* 352 */
    if (codeerr != 0) {
        switch (codeerr) {
            case 1:
                strcpy(symbol->errtxt, "No such file or file unreadable (D62)");
                error_number = ZINT_ERROR_INVALID_OPTION;
                break;
            case 2:
                strcpy(symbol->errtxt, "Input string too long (D63)");
                error_number = ZINT_ERROR_TOO_LONG;
                break;
            case 3:
                strcpy(symbol->errtxt, "Number of codewords per row too small (D64)");
                error_number = ZINT_WARN_INVALID_OPTION;
                break;
            case 4:
                strcpy(symbol->errtxt, "Data too long for specified number of columns (D65)");
                error_number = ZINT_ERROR_TOO_LONG;
                break;
            default:
                strcpy(symbol->errtxt, "Something strange happened (D66)");
                error_number = ZINT_ERROR_ENCODING_PROBLEM;
                break;
        }
    }

    /* 364 */
    return error_number;
919
920
921
922
923
924
925

926
927
928
929








930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
            }
        }
    }

    /* 541 - now compress the data */
    indexchaine = 0;
    mclength = 0;

    if (symbol->output_options & READER_INIT) {
        chainemc[mclength] = 921; /* Reader Initialisation */
        mclength++;
    }








    for (i = 0; i < indexliste; i++) {
        switch (liste[1][i]) {
            case TEX: /* 547 - text mode */
                textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
            case BYT: /* 670 - octet stream mode */
                byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i);
                break;
            case NUM: /* 712 - numeric mode */
                numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
        }
        indexchaine = indexchaine + liste[0][i];
    }

    /* This is where it all changes! */

    if (mclength > 126) {
        strcpy(symbol->errtxt, "Input data too long");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->option_2 > 4) {
        strcpy(symbol->errtxt, "Specified width out of range");
        symbol->option_2 = 0;
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if (debug) {
        printf("\nEncoded Data Stream:\n");
        for (i = 0; i < mclength; i++) {
            printf("0x%02X ", chainemc[i]);
        }
        printf("\n");
    }

    /* Now figure out which variant of the symbol to use and load values accordingly */

    variant = 0;

    if ((symbol->option_2 == 1) && (mclength > 20)) {
        /* the user specified 1 column but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if ((symbol->option_2 == 2) && (mclength > 37)) {
        /* the user specified 2 columns but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if ((symbol->option_2 == 3) && (mclength > 82)) {
        /* the user specified 3 columns but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if (symbol->option_2 == 1) {
        /* the user specified 1 column and the data does fit */
        variant = 6;
        if (mclength <= 16) {







>




>
>
>
>
>
>
>
>


















|



|



















|






|






|







928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
            }
        }
    }

    /* 541 - now compress the data */
    indexchaine = 0;
    mclength = 0;
    
    if (symbol->output_options & READER_INIT) {
        chainemc[mclength] = 921; /* Reader Initialisation */
        mclength++;
    }
    
    if (symbol->eci != 3) {
        chainemc[mclength] = 927; /* ECI */
        mclength++;
        chainemc[mclength] = symbol->eci;
        mclength++;
    }
    
    for (i = 0; i < indexliste; i++) {
        switch (liste[1][i]) {
            case TEX: /* 547 - text mode */
                textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
            case BYT: /* 670 - octet stream mode */
                byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i);
                break;
            case NUM: /* 712 - numeric mode */
                numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i);
                break;
        }
        indexchaine = indexchaine + liste[0][i];
    }

    /* This is where it all changes! */

    if (mclength > 126) {
        strcpy(symbol->errtxt, "Input data too long (D67)");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->option_2 > 4) {
        strcpy(symbol->errtxt, "Specified width out of range (D68)");
        symbol->option_2 = 0;
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if (debug) {
        printf("\nEncoded Data Stream:\n");
        for (i = 0; i < mclength; i++) {
            printf("0x%02X ", chainemc[i]);
        }
        printf("\n");
    }

    /* Now figure out which variant of the symbol to use and load values accordingly */

    variant = 0;

    if ((symbol->option_2 == 1) && (mclength > 20)) {
        /* the user specified 1 column but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data (D69)");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if ((symbol->option_2 == 2) && (mclength > 37)) {
        /* the user specified 2 columns but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data (D6A)");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if ((symbol->option_2 == 3) && (mclength > 82)) {
        /* the user specified 3 columns but the data doesn't fit - go to automatic */
        symbol->option_2 = 0;
        strcpy(symbol->errtxt, "Specified symbol size too small for data (D6B)");
        codeerr = ZINT_WARN_INVALID_OPTION;
    }

    if (symbol->option_2 == 1) {
        /* the user specified 1 column and the data does fit */
        variant = 6;
        if (mclength <= 16) {
Changes to jni/zint/backend/plessey.c.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

    unsigned int i, check;
    unsigned char *checkptr;
    static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1};
    char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */
    int error_number;

    error_number = 0;

    if (length > 65) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    checkptr = (unsigned char *) calloc(1, length * 4 + 8);

    /* Start character */
    strcpy(dest, "31311331");








<
<

|




|







53
54
55
56
57
58
59


60
61
62
63
64
65
66
67
68
69
70
71
72
73

    unsigned int i, check;
    unsigned char *checkptr;
    static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1};
    char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */
    int error_number;



    if (length > 65) {
        strcpy(symbol->errtxt, "Input too long (C70)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(SSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C71)");
        return error_number;
    }
    checkptr = (unsigned char *) calloc(1, length * 4 + 8);

    /* Start character */
    strcpy(dest, "31311331");

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* Plain MSI Plessey - does not calculate any check character */
int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) {

    unsigned int i;
    char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */

    if (length > 55) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    for (i = 0; i < length; i++) {







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Plain MSI Plessey - does not calculate any check character */
int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) {

    unsigned int i;
    char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */

    if (length > 55) {
        strcpy(symbol->errtxt, "Input too long (C72)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    for (i = 0; i < length; i++) {
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    char un[200], tri[32];
    int error_number, h;
    char dest[1000];

    error_number = 0;

    if (length > 18) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    char un[200], tri[32];
    int error_number, h;
    char dest[1000];

    error_number = 0;

    if (length > 18) {
        strcpy(symbol->errtxt, "Input too long (C73)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    int error_number, h;
    char dest[1000];

    error_number = 0;

    if (src_len > 18) {
        /* No Entry Stack Smashers! limit because of str->number conversion*/
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */







|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    int error_number, h;
    char dest[1000];

    error_number = 0;

    if (src_len > 18) {
        /* No Entry Stack Smashers! limit because of str->number conversion*/
        strcpy(symbol->errtxt, "Input too long (C74)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    int i, weight, x, check;
    int error_number;
    char dest[1000];

    error_number = 0;

    if (src_len > 55) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */







|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
    int i, weight, x, check;
    int error_number;
    char dest[1000];

    error_number = 0;

    if (src_len > 55) {
        strcpy(symbol->errtxt, "Input too long (C75)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    char dest[1000];
    unsigned char temp[32];
    unsigned int temp_len;

    error_number = 0;

    if (src_len > 18) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */







|







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    char dest[1000];
    unsigned char temp[32];
    unsigned int temp_len;

    error_number = 0;

    if (src_len > 18) {
        strcpy(symbol->errtxt, "Input too long (C76)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* start character */
    strcpy(dest, "21");

    /* draw data section */
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
}

int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) {
    int error_number;

    error_number = is_sane(NEON, source, length);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Invalid characters in input data");
        return ZINT_ERROR_INVALID_DATA;
    }


    if ((symbol->option_2 < 0) || (symbol->option_2 > 4)) {
        symbol->option_2 = 0;
    }







|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
}

int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) {
    int error_number;

    error_number = is_sane(NEON, source, length);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Invalid characters in input data (C77)");
        return ZINT_ERROR_INVALID_DATA;
    }


    if ((symbol->option_2 < 0) || (symbol->option_2 > 4)) {
        symbol->option_2 = 0;
    }
Changes to jni/zint/backend/png.c.
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    SUCH DAMAGE.
 */

#include <stdio.h>
#ifdef _MSC_VER
#include <fcntl.h>
#include <io.h>

#endif
#include <stdlib.h>
#include <string.h>
#include "common.h"

#ifdef _MSC_VER
#include <malloc.h> 
#endif /* _MSC_VER */

#ifndef NO_PNG
#include <png.h>
#include <zlib.h>
#include <setjmp.h>
#endif /* NO_PNG */
#include "maxipng.h"	/* Maxicode shapes */

#include "font.h"	/* Font for human readable text */

#define SSET	"0123456789ABCDEF"

#define	PNG_DATA	100
#define	BMP_DATA	200

#ifndef NO_PNG

struct mainprog_info_type {
    long width;
    long height;
    FILE *outfile;
    jmp_buf jmpbuf;
};

static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) {
    struct mainprog_info_type *graphic;

    fprintf(stderr, "writepng libpng error: %s\n", msg);
    fflush(stderr);

    graphic = (struct mainprog_info_type*) png_get_error_ptr(png_ptr);
    if (graphic == NULL) {
        /* we are completely hosed now */
        fprintf(stderr,
                "writepng severe error:  jmpbuf not recoverable; terminating.\n");
        fflush(stderr);
        return;
    }
    longjmp(graphic->jmpbuf, 1);
}

int png_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) {
    struct mainprog_info_type wpng_info;
    struct mainprog_info_type *graphic;
    png_structp png_ptr;
    png_infop info_ptr;
    unsigned char *image_data;
    int i, row, column, errno;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;

#ifndef _MSC_VER
    unsigned char outdata[image_width * 3];
#else
    unsigned char* outdata = (unsigned char*) _alloca(image_width * 3);
#endif

    graphic = &wpng_info;

    switch (rotate_angle) {
        case 0:
        case 180:
            graphic->width = image_width;
            graphic->height = image_height;
            break;
        case 90:
        case 270:
            graphic->width = image_height;
            graphic->height = image_width;
            break;
    }

    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    errno = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (errno == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    errno = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour));
    if (errno == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);

    /* Open output file in binary mode */
    if ((symbol->output_options & BARCODE_STDOUT) != 0) {
#ifdef _MSC_VER
        if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
#endif
        graphic->outfile = stdout;
    } else {
        if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    /* Set up error handling routine as proc() above */
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic, writepng_error_handler, NULL);
    if (!png_ptr) {
        strcpy(symbol->errtxt, "Out of memory");
        return ZINT_ERROR_MEMORY;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, NULL);
        strcpy(symbol->errtxt, "Out of memory");
        return ZINT_ERROR_MEMORY;
    }

    /* catch jumping here */
    if (setjmp(graphic->jmpbuf)) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        strcpy(symbol->errtxt, "libpng error occurred");
        return ZINT_ERROR_MEMORY;
    }

    /* open output file with libpng */
    png_init_io(png_ptr, graphic->outfile);

    /* set compression */







>





<
<
<
<




<
<
<
<



<
<
<
<
<










|






|






|





|



|

|



|
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|









|







|






|






|







30
31
32
33
34
35
36
37
38
39
40
41
42




43
44
45
46




47
48
49





50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90



91
92






























93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    SUCH DAMAGE.
 */

#include <stdio.h>
#ifdef _MSC_VER
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "common.h"





#ifndef NO_PNG
#include <png.h>
#include <zlib.h>
#include <setjmp.h>





#define SSET	"0123456789ABCDEF"






struct mainprog_info_type {
    long width;
    long height;
    FILE *outfile;
    jmp_buf jmpbuf;
};

static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) {
    struct mainprog_info_type *graphic;

    fprintf(stderr, "writepng libpng error: %s (F30)\n", msg);
    fflush(stderr);

    graphic = (struct mainprog_info_type*) png_get_error_ptr(png_ptr);
    if (graphic == NULL) {
        /* we are completely hosed now */
        fprintf(stderr,
                "writepng severe error:  jmpbuf not recoverable; terminating. (F31)\n");
        fflush(stderr);
        return;
    }
    longjmp(graphic->jmpbuf, 1);
}

int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
    struct mainprog_info_type wpng_info;
    struct mainprog_info_type *graphic;
    png_structp png_ptr;
    png_infop info_ptr;
    unsigned char *image_data;
    int i, row, column;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;

#ifndef _MSC_VER
    unsigned char outdata[symbol->bitmap_width * 3];
#else
    unsigned char* outdata = (unsigned char*) _alloca(symbol->bitmap_width * 3);
#endif

    graphic = &wpng_info;
    



    graphic->width = symbol->bitmap_width;
    graphic->height = symbol->bitmap_height;































    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);

    /* Open output file in binary mode */
    if (symbol->output_options & BARCODE_STDOUT) {
#ifdef _MSC_VER
        if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
            strcpy(symbol->errtxt, "Can't open output file");
            return ZINT_ERROR_FILE_ACCESS;
        }
#endif
        graphic->outfile = stdout;
    } else {
        if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) {
            strcpy(symbol->errtxt, "Can't open output file (F32)");
            return ZINT_ERROR_FILE_ACCESS;
        }
    }

    /* Set up error handling routine as proc() above */
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic, writepng_error_handler, NULL);
    if (!png_ptr) {
        strcpy(symbol->errtxt, "Out of memory (F33)");
        return ZINT_ERROR_MEMORY;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, NULL);
        strcpy(symbol->errtxt, "Out of memory (F34)");
        return ZINT_ERROR_MEMORY;
    }

    /* catch jumping here */
    if (setjmp(graphic->jmpbuf)) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        strcpy(symbol->errtxt, "libpng error occurred (F35)");
        return ZINT_ERROR_MEMORY;
    }

    /* open output file with libpng */
    png_init_io(png_ptr, graphic->outfile);

    /* set compression */
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
    png_write_info(png_ptr, info_ptr);

    /* set up the transformations:  for now, just pack low-bit-depth pixels
    into bytes (one, two or four pixels per byte) */
    png_set_packing(png_ptr);

    /* Pixel Plotting */

    switch (rotate_angle) {
        case 0: /* Plot the right way up */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    i = column * 3;
                    switch (*(pixelbuf + (image_width * row) + column)) {
                        case '1':
                            outdata[i] = fgred;
                            outdata[i + 1] = fggrn;
                            outdata[i + 2] = fgblu;
                            break;
                        default:
                            outdata[i] = bgred;
                            outdata[i + 1] = bggrn;
                            outdata[i + 2] = bgblu;
                            break;

                    }
                }
                /* write row contents to file */
                image_data = outdata;
                png_write_row(png_ptr, image_data);
            }
            break;
        case 90: /* Plot 90 degrees clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    i = column * 3;
                    switch (*(pixelbuf + (image_width * (image_height - column - 1)) + row)) {
                        case '1':
                            outdata[i] = fgred;
                            outdata[i + 1] = fggrn;
                            outdata[i + 2] = fgblu;
                            break;
                        default:
                            outdata[i] = bgred;
                            outdata[i + 1] = bggrn;
                            outdata[i + 2] = bgblu;
                            break;

                    }
                }

                /* write row contents to file */
                image_data = outdata;
                png_write_row(png_ptr, image_data);
            }
            break;
        case 180: /* Plot upside down */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    i = column * 3;
                    switch (*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) {
                        case '1':
                            outdata[i] = fgred;
                            outdata[i + 1] = fggrn;
                            outdata[i + 2] = fgblu;
                            break;
                        default:
                            outdata[i] = bgred;
                            outdata[i + 1] = bggrn;
                            outdata[i + 2] = bgblu;
                            break;

                    }
                }

                /* write row contents to file */
                image_data = outdata;
                png_write_row(png_ptr, image_data);
            }
            break;
        case 270: /* Plot 90 degrees anti-clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    i = column * 3;
                    switch (*(pixelbuf + (image_width * column) + (image_width - row - 1))) {
                        case '1':
                            outdata[i] = fgred;
                            outdata[i + 1] = fggrn;
                            outdata[i + 2] = fgblu;
                            break;
                        default:
                            outdata[i] = bgred;
                            outdata[i + 1] = bggrn;
                            outdata[i + 2] = bgblu;
                            break;

                    }
                }

                /* write row contents to file */
                image_data = outdata;
                png_write_row(png_ptr, image_data);
            }
            break;
    }

    /* End the file */
    png_write_end(png_ptr, NULL);

    /* make sure we have disengaged */
    if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(wpng_info.outfile);
    } else {
        fclose(wpng_info.outfile);
    }
    return 0;
}
#endif /* NO_PNG */

int bmp_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) {
    int i, row, column, errno;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;

    switch (rotate_angle) {
        case 0:
        case 180:
            symbol->bitmap_width = image_width;
            symbol->bitmap_height = image_height;
            break;
        case 90:
        case 270:
            symbol->bitmap_width = image_height;
            symbol->bitmap_height = image_width;
            break;
    }

    if (symbol->bitmap != NULL)
        free(symbol->bitmap);

    symbol->bitmap = (char *) malloc(image_width * image_height * 3);


    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    errno = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (errno == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }
    errno = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->fgcolour));
    if (errno == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target");
        return ZINT_ERROR_INVALID_OPTION;
    }

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);

    /* Pixel Plotting */
    i = 0;
    switch (rotate_angle) {
        case 0: /* Plot the right way up */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    switch (*(pixelbuf + (image_width * row) + column)) {
                        case '1':
                            symbol->bitmap[i++] = fgred;
                            symbol->bitmap[i++] = fggrn;
                            symbol->bitmap[i++] = fgblu;
                            break;
                        default:
                            symbol->bitmap[i++] = bgred;
                            symbol->bitmap[i++] = bggrn;
                            symbol->bitmap[i++] = bgblu;
                            break;

                    }
                }
            }
            break;
        case 90: /* Plot 90 degrees clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    switch (*(pixelbuf + (image_width * (image_height - column - 1)) + row)) {
                        case '1':
                            symbol->bitmap[i++] = fgred;
                            symbol->bitmap[i++] = fggrn;
                            symbol->bitmap[i++] = fgblu;
                            break;
                        default:
                            symbol->bitmap[i++] = bgred;
                            symbol->bitmap[i++] = bggrn;
                            symbol->bitmap[i++] = bgblu;
                            break;

                    }
                }
            }
            break;
        case 180: /* Plot upside down */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    switch (*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) {
                        case '1':
                            symbol->bitmap[i++] = fgred;
                            symbol->bitmap[i++] = fggrn;
                            symbol->bitmap[i++] = fgblu;
                            break;
                        default:
                            symbol->bitmap[i++] = bgred;
                            symbol->bitmap[i++] = bggrn;
                            symbol->bitmap[i++] = bgblu;
                            break;

                    }
                }
            }
            break;
        case 270: /* Plot 90 degrees anti-clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    switch (*(pixelbuf + (image_width * column) + (image_width - row - 1))) {
                        case '1':
                            symbol->bitmap[i++] = fgred;
                            symbol->bitmap[i++] = fggrn;
                            symbol->bitmap[i++] = fgblu;
                            break;
                        default:
                            symbol->bitmap[i++] = bgred;
                            symbol->bitmap[i++] = bggrn;
                            symbol->bitmap[i++] = bgblu;
                            break;

                    }
                }
            }
            break;
    }

    return 0;
}

int png_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) {
    int error_number;
    float scaler = symbol->scale;
    char *scaled_pixelbuf;
    int horiz, vert, i;
    int scale_width, scale_height;

    if (scaler == 0) {
        scaler = 0.5;
    }
    scale_width = image_width * scaler;
    scale_height = image_height * scaler;

    /* Apply scale options by creating another pixel buffer */
    if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
        printf("Insufficient memory for pixel buffer");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (scale_width * scale_height); i++) {
            *(scaled_pixelbuf + i) = '0';
        }
    }

    for (vert = 0; vert < scale_height; vert++) {
        for (horiz = 0; horiz < scale_width; horiz++) {
            *(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler));
        }
    }

    if (image_type == PNG_DATA) {
#ifndef NO_PNG
        error_number = png_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
#else
        return ZINT_ERROR_INVALID_OPTION;
#endif
    } else {
        error_number = bmp_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
    }

    free(scaled_pixelbuf);

    return error_number;
}

void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) {
    /* Draw a rectangle */
    int i, j, png_ypos;

    png_ypos = image_height - ypos - ylen;
    /* This fudge is needed because EPS measures height from the bottom up but
    PNG measures y position from the top down */

    for (i = (xpos); i < (xpos + xlen); i++) {
        for (j = (png_ypos); j < (png_ypos + ylen); j++) {
            *(pixelbuf + (image_width * j) + i) = '1';
        }
    }
}

int bullseye_pixel(int row, int col) {
    int block_val, block_pos, return_val;

    block_val = bullseye_compressed[(row * 12) + (col / 8)];
    return_val = 0;
    block_pos = col % 8;

    if (block_val & (0x80 >> block_pos)) {
        return_val = 1;
    }

    return return_val;
}

void draw_bullseye(char *pixelbuf, int image_width, int xoffset, int yoffset) {
    /* Central bullseye in Maxicode symbols */
    int i, j;

    for (j = 103; j < 196; j++) {
        for (i = 0; i < 93; i++) {
            if (bullseye_pixel(j - 103, i)) {
                /* if(bullseye[(((j - 103) * 93) + i)] == 1) { */
                *(pixelbuf + (image_width * j) + (image_width * yoffset) + i + 99 + xoffset) = '1';
            }
        }
    }
}

void draw_hexagon(char *pixelbuf, int image_width, int xposn, int yposn) {
    /* Put a hexagon into the pixel buffer */
    int i, j;

    for (i = 0; i < 12; i++) {
        for (j = 0; j < 10; j++) {
            if (hexagon[(i * 10) + j] == 1) {
                *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = '1';
            }
        }
    }
}

void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int smalltext, int image_width, int image_height) {
    /* Put a letter into a position */
    int skip, x, y, glyph_no;

    skip = 0;

    if (letter < 33) {
        skip = 1;
    }
    if ((letter > 127) && (letter < 161)) {
        skip = 1;
    }

    if (skip == 0) {
        if (letter > 128) {
            glyph_no = letter - 66;
        } else {
            glyph_no = letter - 33;
        }
        
        
        if (smalltext) {
            for (y = 0; y < 9; y++) {
                for (x = 0; x < 5; x++) {
                    if (small_font[(glyph_no * 8) + y] & (0x10 >> x)) {
                        *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1';
                    }
                }
            }
        } else {
            for (y = 0; y < 14; y++) {
                for (x = 0; x < 7; x++) {
                    if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) {
                        *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1';
                    }
                }
            }
        }
    }
}

/* Plot a string into the pixel buffer */
void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int smalltext, int image_width, int image_height) {
    int i, string_length, string_left_hand;

    string_length = strlen(input_string);
    string_left_hand = xposn - ((7 * string_length) / 2);

    for (i = 0; i < string_length; i++) {
        draw_letter(pixbuf, input_string[i], string_left_hand + (i * 7), yposn, smalltext, image_width, image_height);
    }

}

int maxi_png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) {
    int i, row, column, xposn, yposn;
    int image_height, image_width;
    char *pixelbuf;
    int error_number;
    int xoffset, yoffset;

    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;
    image_width = 300 + (2 * xoffset * 2);
    image_height = 300 + (2 * yoffset * 2);

    if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
        printf("Insifficient memory for pixel buffer");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (image_width * image_height); i++) {
            *(pixelbuf + i) = '0';
        }
    }

    draw_bullseye(pixelbuf, image_width, (2 * xoffset), (2 * yoffset));

    for (row = 0; row < symbol->rows; row++) {
        yposn = row * 9;
        for (column = 0; column < symbol->width; column++) {
            xposn = column * 10;
            if (module_is_set(symbol, row, column)) {
                if (row & 1) {
                    /* Odd (reduced) row */
                    xposn += 5;
                    draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset));
                } else {
                    /* Even (full) row */
                    draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset));
                }
            }
        }
    }

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        /* boundary bars */
        draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height);
        draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height);
    }

    if ((symbol->output_options & BARCODE_BOX) != 0) {
        /* side bars */
        draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height);
        draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height);
    }

    error_number = png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
    free(pixelbuf);
    return error_number;
}

/* Convert UTF-8 to Latin1 Codepage for the interpretation line */
void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
    int j, i, input_length;

    input_length = ustrlen(source);

    j = 0;
    i = 0;
    while (i < input_length) {
        switch (source[i]) {
            case 0xC2:
                /* UTF-8 C2xxh */
                /* Character range: C280h (latin: 80h) to C2BFh (latin: BFh) */
                i++;
                preprocessed[j] = source[i];
                j++;
                break;
            case 0xC3:
                /* UTF-8 C3xx */
                /* Character range: C380h (latin: C0h) to C3BFh (latin: FFh) */
                i++;
                preprocessed[j] = source[i] + 64;
                j++;
                break;
            default:
                /* Process ASCII (< 80h), all other unicode points are ignored */
                if (source[i] < 128) {
                    preprocessed[j] = source[i];
                    j++;
                }
                break;
        }
        i++;
    }
    preprocessed[j] = '\0';

    return;
}

int png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) {
    int textdone, main_width, comp_offset, large_bar_count;
    char textpart[10], addon[6];
    float addon_text_posn, preset_height, large_bar_height;
    int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height;
    char *pixelbuf;
    int addon_latch = 0, smalltext = 0;
    int this_row, block_width, plot_height, plot_yposn, textpos;
    float row_height, row_posn;
    int error_number;
    int default_text_posn;
    int next_yposn;
#ifndef _MSC_VER
    unsigned char local_text[ustrlen(symbol->text) + 1];
#else
    unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1);
#endif

    if (symbol->show_hrt != 0) {
        to_latin1(symbol->text, local_text);
    } else {
        local_text[0] = '\0';
    }

    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;
    row_height = 0;
    if (symbol->output_options & SMALL_TEXT) {
        smalltext = 1;
    }

    if (symbol->height == 0) {
        symbol->height = 50;
    }

    large_bar_count = 0;
    preset_height = 0.0;
    for (i = 0; i < symbol->rows; i++) {
        preset_height += symbol->row_height[i];
        if (symbol->row_height[i] == 0) {
            large_bar_count++;
        }
    }

    if (large_bar_count == 0) {
        symbol->height = preset_height;
        large_bar_height = 10;
    } else {
        large_bar_height = (symbol->height - preset_height) / large_bar_count;
    }

    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(local_text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;
                break;
            default:
                main_width = 68 + comp_offset;
        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        if (symbol->whitespace_width == 0) {
            symbol->whitespace_width = 10;
            main_width = 96 + comp_offset;
        }
    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        if (symbol->whitespace_width == 0) {
            symbol->whitespace_width = 10;
            main_width = 51 + comp_offset;
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(local_text); i++) {
            if (latch == 1) {
                addon[r] = local_text[i];
                r++;
            }
            if (symbol->text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';

    if (ustrlen(local_text) != 0) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }
    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;
    image_width = 2 * (symbol->width + xoffset + xoffset);
    image_height = 2 * (symbol->height + textoffset + yoffset + yoffset);

    if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
        printf("Insufficient memory for pixel buffer");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (image_width * image_height); i++) {
            *(pixelbuf + i) = '0';
        }
    }

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        default_text_posn = image_height - 17;
    } else {
        default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width;
    }

    row_posn = textoffset + yoffset;
    next_yposn = textoffset + yoffset;
    row_height = 0;

    /* Plot the body of the symbol to the pixel buffer */
    for (r = 0; r < symbol->rows; r++) {
        this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
        row_posn += row_height;
        plot_yposn = next_yposn;
        if (symbol->row_height[this_row] == 0) {
            row_height = large_bar_height;
        } else {
            row_height = symbol->row_height[this_row];
        }
        next_yposn = (int) (row_posn + row_height);
        plot_height = next_yposn - plot_yposn;

        i = 0;
        if (module_is_set(symbol, this_row, 0)) {
            latch = 1;
        } else {
            latch = 0;
        }

        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
            if ((addon_latch == 0) && (r == 0) && (i > main_width)) {
                plot_height = (int) (row_height - 5.0);
                plot_yposn = (int) (row_posn - 5.0);
                addon_text_posn = row_posn + row_height - 8.0;
                addon_latch = 1;
            }
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;

        } while (i < symbol->width);
    }

    xoffset += comp_offset;

    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) {
        /* guard bar extensions and text formatting for EAN8 and EAN13 */
        switch (ustrlen(local_text)) {
            case 8: /* EAN-8 */
            case 11:
            case 14:
                draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                for (i = 0; i < 4; i++) {
                    textpart[i] = symbol->text[i];
                }
                textpart[4] = '\0';
                textpos = 2 * (17 + xoffset);

                draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
                for (i = 0; i < 4; i++) {
                    textpart[i] = symbol->text[i + 4];
                }
                textpart[4] = '\0';
                textpos = 2 * (50 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = 2 * (xoffset + 86);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                        break;
                    case 5:
                        textpos = 2 * (xoffset + 100);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                        break;
                }

                break;
            case 13: /* EAN 13 */
            case 16:
            case 19:
                draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);

                textpart[0] = symbol->text[0];
                textpart[1] = '\0';
                textpos = 2 * (-7 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
                for (i = 0; i < 6; i++) {
                    textpart[i] = symbol->text[i + 1];
                }
                textpart[6] = '\0';
                textpos = 2 * (24 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
                for (i = 0; i < 6; i++) {
                    textpart[i] = symbol->text[i + 7];
                }
                textpart[6] = '\0';
                textpos = 2 * (71 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = 2 * (xoffset + 114);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                        break;
                    case 5:
                        textpos = 2 * (xoffset + 128);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                        break;
                }
                break;

        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        /* guard bar extensions and text formatting for UPCA */
        latch = 1;

        i = 0 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 11 + comp_offset);
        draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        latch = 1;
        i = 85 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 96 + comp_offset);
        textpart[0] = symbol->text[0];
        textpart[1] = '\0';
        textpos = 2 * (-5 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        for (i = 0; i < 5; i++) {
            textpart[i] = symbol->text[i + 1];
        }
        textpart[5] = '\0';
        textpos = 2 * (27 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        for (i = 0; i < 5; i++) {
            textpart[i] = symbol->text[i + 6];
        }
        textpart[6] = '\0';
        textpos = 2 * (68 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        textpart[0] = symbol->text[11];
        textpart[1] = '\0';
        textpos = 2 * (100 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = 2 * (xoffset + 116);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                break;
            case 5:
                textpos = 2 * (xoffset + 130);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                break;
        }

    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        /* guard bar extensions and text formatting for UPCE */
        draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);

        textpart[0] = symbol->text[0];
        textpart[1] = '\0';
        textpos = 2 * (-5 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        for (i = 0; i < 6; i++) {
            textpart[i] = symbol->text[i + 1];
        }
        textpart[6] = '\0';
        textpos = 2 * (24 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        textpart[0] = symbol->text[7];
        textpart[1] = '\0';
        textpos = 2 * (55 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height);
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = 2 * (xoffset + 70);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                break;
            case 5:
                textpos = 2 * (xoffset + 84);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
                break;
        }

    }

    xoffset -= comp_offset;

    /* Put boundary bars or box around symbol */
    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        /* boundary bars */
        draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height);
        draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height);
        if ((symbol->output_options & BARCODE_BIND) != 0) {
            if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                /* row binding */
                for (r = 1; r < symbol->rows; r++) {
                    draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height);
                }
            }
        }
    }

    if ((symbol->output_options & BARCODE_BOX) != 0) {
        /* side bars */
        draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height);
        draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height);
    }

    /* Put the human readable text at the bottom */
    if ((textdone == 0) && (ustrlen(local_text) != 0)) {
        textpos = (image_width / 2);
        draw_string(pixelbuf, (char*) local_text, textpos, default_text_posn, smalltext, image_width, image_height);
    }

    error_number = png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
    free(pixelbuf);
    return error_number;
}

#ifndef NO_PNG

int png_handle(struct zint_symbol *symbol, int rotate_angle) {
    int error;

    if (symbol->symbology == BARCODE_MAXICODE) {
        error = maxi_png_plot(symbol, rotate_angle, PNG_DATA);
    } else {

        error = png_plot(symbol, rotate_angle, PNG_DATA);
    }

    return error;
}
#endif /* NO_PNG */

int bmp_handle(struct zint_symbol *symbol, int rotate_angle) {
    int error;

    if (symbol->symbology == BARCODE_MAXICODE) {
        error = maxi_png_plot(symbol, rotate_angle, BMP_DATA);
    } else {
        error = png_plot(symbol, rotate_angle, BMP_DATA);
    }

    return error;
}







<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
150
151
152
153
154
155
156



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176










































































177
178
179
180
181
182
183
184
185
186
187
188
189
190
191


















































































































































































































































































































































































































































































































































































































































































































































































































































    png_write_info(png_ptr, info_ptr);

    /* set up the transformations:  for now, just pack low-bit-depth pixels
    into bytes (one, two or four pixels per byte) */
    png_set_packing(png_ptr);

    /* Pixel Plotting */



    for (row = 0; row < symbol->bitmap_height; row++) {
        for (column = 0; column < symbol->bitmap_width; column++) {
            i = column * 3;
            switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) {
                case '1':
                    outdata[i] = fgred;
                    outdata[i + 1] = fggrn;
                    outdata[i + 2] = fgblu;
                    break;
                default:
                    outdata[i] = bgred;
                    outdata[i + 1] = bggrn;
                    outdata[i + 2] = bgblu;
                    break;

            }
        }
        /* write row contents to file */
        image_data = outdata;
        png_write_row(png_ptr, image_data);










































































    }

    /* End the file */
    png_write_end(png_ptr, NULL);

    /* make sure we have disengaged */
    if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(wpng_info.outfile);
    } else {
        fclose(wpng_info.outfile);
    }
    return 0;
}
#endif /* NO_PNG */


















































































































































































































































































































































































































































































































































































































































































































































































































































Changes to jni/zint/backend/postal.c.
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
    unsigned int i, sum, check_digit;
    int error_number;

    error_number = 0;

    if (length > 38) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    sum = 0;

    /* start character */
    strcpy(dest, "L");








|




|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
    unsigned int i, sum, check_digit;
    int error_number;

    error_number = 0;

    if (length > 38) {
        strcpy(symbol->errtxt, "Input too long (D80)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D81)");
        return error_number;
    }
    sum = 0;

    /* start character */
    strcpy(dest, "L");

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
    unsigned int i, sum, check_digit;
    int error_number;

    error_number = 0;

    if (length > 38) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    sum = 0;

    /* start character */
    strcpy(dest, "L");








|




|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
    unsigned int i, sum, check_digit;
    int error_number;

    error_number = 0;

    if (length > 38) {
        strcpy(symbol->errtxt, "Input too long (D82)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D83)");
        return error_number;
    }
    sum = 0;

    /* start character */
    strcpy(dest, "L");

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/* Korean Postal Authority */
int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) {
    int total, loop, check, zeroes, error_number;
    char localstr[8], dest[80];

    error_number = 0;
    if (length > 6) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    zeroes = 6 - length;
    memset(localstr, '0', zeroes);
    strcpy(localstr + zeroes, (char *) source);

    total = 0;







|




|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/* Korean Postal Authority */
int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) {
    int total, loop, check, zeroes, error_number;
    char localstr[8], dest[80];

    error_number = 0;
    if (length > 6) {
        strcpy(symbol->errtxt, "Input too long (D84)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D85)");
        return error_number;
    }
    zeroes = 6 - length;
    memset(localstr, '0', zeroes);
    strcpy(localstr + zeroes, (char *) source);

    total = 0;
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
int fim(struct zint_symbol *symbol, unsigned char source[], int length) {


    char dest[16] = {0};

    if (length > 1) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }

    switch ((char) source[0]) {
        case 'a':
        case 'A':
            strcpy(dest, "111515111");







|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
int fim(struct zint_symbol *symbol, unsigned char source[], int length) {


    char dest[16] = {0};

    if (length > 1) {
        strcpy(symbol->errtxt, "Input too long (D86)");
        return ZINT_ERROR_TOO_LONG;
    }

    switch ((char) source[0]) {
        case 'a':
        case 'A':
            strcpy(dest, "111515111");
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
            strcpy(dest, "11131313111");
            break;
        case 'd':
        case 'D':
            strcpy(dest, "1111131311111");
            break;
        default:
            strcpy(symbol->errtxt, "Invalid characters in data");
            return ZINT_ERROR_INVALID_DATA;
            break;
    }

    expand(symbol, dest);
    return 0;
}







|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
            strcpy(dest, "11131313111");
            break;
        case 'd':
        case 'D':
            strcpy(dest, "1111131311111");
            break;
        default:
            strcpy(symbol->errtxt, "Invalid characters in data (D87)");
            return ZINT_ERROR_INVALID_DATA;
            break;
    }

    expand(symbol, dest);
    return 0;
}
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    strcat((char*) dest, "0");

    return set_copy[check_digit];
}

/* Puts RM4SCC into the data matrix */
int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
    char height_pattern[200];
    unsigned int loopey, h;
    int writer;
    int error_number;
    strcpy(height_pattern, "");

    error_number = 0;

    if (length > 120) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(KRSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    /*check = */rm4scc((char*) source, (unsigned char*) height_pattern, length);

    writer = 0;
    h = strlen(height_pattern);
    for (loopey = 0; loopey < h; loopey++) {
        if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
            set_module(symbol, 0, writer);
        }
        set_module(symbol, 1, writer);







|







|
|





|



|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    strcat((char*) dest, "0");

    return set_copy[check_digit];
}

/* Puts RM4SCC into the data matrix */
int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
    char height_pattern[210];
    unsigned int loopey, h;
    int writer;
    int error_number;
    strcpy(height_pattern, "");

    error_number = 0;

    if (length > 50) {
        strcpy(symbol->errtxt, "Input too long (D88)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(KRSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D89)");
        return error_number;
    }
    /*check = */rm4scc((char*) source, (unsigned char*) height_pattern, length);
                
    writer = 0;
    h = strlen(height_pattern);
    for (loopey = 0; loopey < h; loopey++) {
        if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
            set_module(symbol, 0, writer);
        }
        set_module(symbol, 1, writer);
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    return error_number;
}

/* Handles Dutch Post TNT KIX symbols
   The same as RM4SCC but without check digit
   Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) {
    char height_pattern[50], localstr[20];
    unsigned int loopey;
    int writer, i, h;
    int error_number; /* zeroes; */
    strcpy(height_pattern, "");

    error_number = 0;

    if (length > 18) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(KRSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    strcpy(localstr, (char *) source);

    /* Encode data */
    for (i = 0; i < 18; i++) {
        lookup(KRSET, RoyalTable, localstr[i], height_pattern);
    }

    writer = 0;
    h = strlen(height_pattern);
    for (loopey = 0; loopey < h; loopey++) {
        if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {







|








|





|




|

|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    return error_number;
}

/* Handles Dutch Post TNT KIX symbols
   The same as RM4SCC but without check digit
   Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) {
    char height_pattern[75], localstr[20];
    unsigned int loopey;
    int writer, i, h;
    int error_number; /* zeroes; */
    strcpy(height_pattern, "");

    error_number = 0;

    if (length > 18) {
        strcpy(symbol->errtxt, "Input too long (D8A)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper(source);
    error_number = is_sane(KRSET, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D8B)");
        return error_number;
    }

    strcpy(localstr, (char *) source);
    
    /* Encode data */
    for (i = 0; i < length; i++) {
        lookup(KRSET, RoyalTable, localstr[i], height_pattern);
    }

    writer = 0;
    h = strlen(height_pattern);
    for (loopey = 0; loopey < h; loopey++) {
        if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    char height_pattern[100];
    unsigned int loopey, h;
    int writer, i, error_number;
    strcpy(height_pattern, "");

    error_number = 0;
    if (length > 50) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper((unsigned char*) source);
    error_number = is_sane(DAFTSET, (unsigned char*) source, length);

    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    for (i = 0; i < length; i++) {
        if (source[i] == 'D') {
            strcat(height_pattern, "2");
        }







|






|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    char height_pattern[100];
    unsigned int loopey, h;
    int writer, i, error_number;
    strcpy(height_pattern, "");

    error_number = 0;
    if (length > 50) {
        strcpy(symbol->errtxt, "Input too long (D8C)");
        return ZINT_ERROR_TOO_LONG;
    }
    to_upper((unsigned char*) source);
    error_number = is_sane(DAFTSET, (unsigned char*) source, length);

    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D8D)");
        return error_number;
    }

    for (i = 0; i < length; i++) {
        if (source[i] == 'D') {
            strcat(height_pattern, "2");
        }
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) {
    int loop, error_number;
    char dest[512]; /* 90 * 4 + 1 ~ */

    error_number = 0;

    if (length > 90) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    *dest = '\0';
    for (loop = 0; loop < length; loop++) {
        lookup(NEON, FlatTable, source[loop], dest);
    }








|




|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) {
    int loop, error_number;
    char dest[512]; /* 90 * 4 + 1 ~ */

    error_number = 0;

    if (length > 90) {
        strcpy(symbol->errtxt, "Input too long (D8E)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D8F)");
        return error_number;
    }
    *dest = '\0';
    for (loop = 0; loop < length; loop++) {
        lookup(NEON, FlatTable, source[loop], dest);
    }

518
519
520
521
522
523
524





525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

#ifndef _MSC_VER
    char local_source[length + 1];
#else
    char* local_source = (char*) _alloca(length + 1);
#endif






    inter_posn = 0;
    error_number = 0;

    strcpy(local_source, (char*) source);
    for (i = 0; i < length; i++) {
        local_source[i] = source[i];
    }
    to_upper((unsigned char*) local_source);
    error_number = is_sane(SHKASUTSET, (unsigned char*) local_source, length);

    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    memset(inter, 'd', 20); /* Pad character CC4 */
    inter[20] = '\0';

    i = 0;
    inter_posn = 0;







>
>
>
>
>











|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

#ifndef _MSC_VER
    char local_source[length + 1];
#else
    char* local_source = (char*) _alloca(length + 1);
#endif

    if (length > 20) {
        strcpy(symbol->errtxt, "Input too long (D8G)");
        return ZINT_ERROR_TOO_LONG;
    }
    
    inter_posn = 0;
    error_number = 0;

    strcpy(local_source, (char*) source);
    for (i = 0; i < length; i++) {
        local_source[i] = source[i];
    }
    to_upper((unsigned char*) local_source);
    error_number = is_sane(SHKASUTSET, (unsigned char*) local_source, length);

    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (D8H)");
        return error_number;
    }
    memset(inter, 'd', 20); /* Pad character CC4 */
    inter[20] = '\0';

    i = 0;
    inter_posn = 0;
Changes to jni/zint/backend/ps.c.
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56





57
58
59
60
61
62
63
64































65
66
67
68
69
70
71



72
73
74
75
76
77
78
79
80




81
82
83
84




85
86
87
88
89




90
91
92
93
94




95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110















































111
112
113
114
115
116
117

int ps_plot(struct zint_symbol *symbol) {
    int i, block_width, latch, r, this_row;
    float textpos, large_bar_height, preset_height, row_height, row_posn;
    FILE *feps;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
    float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper;


    int error_number = 0;
    int textoffset, xoffset, yoffset, textdone, main_width;
    char textpart[10], addon[6];
    int large_bar_count, comp_offset;
    float addon_text_posn;
    float scaler = symbol->scale;
    float default_text_posn;
    int plot_text = 1;
    const char *locale = NULL;






    row_height = 0;
    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;
































    if ((symbol->output_options & BARCODE_STDOUT) != 0) {
        feps = stdout;
    } else {
        feps = fopen(symbol->outfile, "w");
    }
    if (feps == NULL) {
        strcpy(symbol->errtxt, "Could not open output file");



        return ZINT_ERROR_FILE_ACCESS;
    }

    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");




        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target");




        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");




        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target");




        return ZINT_ERROR_INVALID_OPTION;
    }
    locale = setlocale(LC_ALL, "C");

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
    red_ink = fgred / 256.0;
    green_ink = fggrn / 256.0;
    blue_ink = fgblu / 256.0;
    red_paper = bgred / 256.0;
    green_paper = bggrn / 256.0;
    blue_paper = bgblu / 256.0;
















































    if (symbol->height == 0) {
        symbol->height = 50;
    }

    large_bar_count = 0;
    preset_height = 0.0;







>
>







<

>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|





|
>
>
>








|
>
>
>
>



|
>
>
>
>




|
>
>
>
>




|
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

int ps_plot(struct zint_symbol *symbol) {
    int i, block_width, latch, r, this_row;
    float textpos, large_bar_height, preset_height, row_height, row_posn;
    FILE *feps;
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
    float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper;
    float cyan_ink, magenta_ink, yellow_ink, black_ink;
    float cyan_paper, magenta_paper, yellow_paper, black_paper;
    int error_number = 0;
    int textoffset, xoffset, yoffset, textdone, main_width;
    char textpart[10], addon[6];
    int large_bar_count, comp_offset;
    float addon_text_posn;
    float scaler = symbol->scale;
    float default_text_posn;

    const char *locale = NULL;
#ifndef _MSC_VER
    unsigned char local_text[ustrlen(symbol->text) + 1];
#else
    unsigned char* local_text = (unsigned char*) malloc(ustrlen(symbol->text) + 1);
#endif    

    row_height = 0;
    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;

    if (symbol->show_hrt != 0) {
        /* Copy text from symbol */
        ustrcpy(local_text, symbol->text);
    } else {
        /* No text needed */
        switch (symbol->symbology) {
            case BARCODE_EANX:
            case BARCODE_EANX_CC:
            case BARCODE_ISBNX:
            case BARCODE_UPCA:
            case BARCODE_UPCE:
            case BARCODE_UPCA_CC:
            case BARCODE_UPCE_CC:
                /* For these symbols use dummy text to ensure formatting is done
                 * properly even if no text is required */
                for (i = 0; i < ustrlen(symbol->text); i++) {
                    if (symbol->text[i] == '+') {
                        local_text[i] = '+';
                    } else {
                        local_text[i] = ' ';
                    }
                    local_text[ustrlen(symbol->text)] = '\0';
                }
                break;
            default:
                /* For everything else, just remove the text */
                local_text[0] = '\0';
                break;
        }
    }

    if (symbol->output_options & BARCODE_STDOUT) {
        feps = stdout;
    } else {
        feps = fopen(symbol->outfile, "w");
    }
    if (feps == NULL) {
        strcpy(symbol->errtxt, "Could not open output file (F40)");
#ifdef _MSC_VER
        free(local_text);
#endif
        return ZINT_ERROR_FILE_ACCESS;
    }

    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F41)");
        fclose(feps);
#ifdef _MSC_VER
        free(local_text);
#endif
        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target (F42)");
        fclose(feps);
#ifdef _MSC_VER
        free(local_text);
#endif
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F43)");
        fclose(feps);
#ifdef _MSC_VER
        free(local_text);
#endif
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target (F44)");
        fclose(feps);
#ifdef _MSC_VER
        free(local_text);
#endif
        return ZINT_ERROR_INVALID_OPTION;
    }
    locale = setlocale(LC_ALL, "C");

    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
    red_ink = fgred / 256.0;
    green_ink = fggrn / 256.0;
    blue_ink = fgblu / 256.0;
    red_paper = bgred / 256.0;
    green_paper = bggrn / 256.0;
    blue_paper = bgblu / 256.0;

    /* Convert RGB to CMYK */
    if (red_ink > green_ink) {
        if (blue_ink > red_ink) {
            black_ink = 1 - blue_ink;
        } else {
            black_ink = 1 - red_ink;
        }
    } else {
        if (blue_ink > red_ink) {
            black_ink = 1 - blue_ink;
        } else {
            black_ink = 1 - green_ink;
        }
    }
    if (black_ink < 1.0) {
        cyan_ink = (1 - red_ink - black_ink) / (1 - black_ink);
        magenta_ink = (1 - green_ink - black_ink) / (1 - black_ink);
        yellow_ink = (1 - blue_ink - black_ink) / (1 - black_ink);
    } else {
        cyan_ink = 0.0;
        magenta_ink = 0.0;
        yellow_ink = 0.0;
    }

    if (red_paper > green_paper) {
        if (blue_paper > red_paper) {
            black_paper = 1 - blue_paper;
        } else {
            black_paper = 1 - red_paper;
        }
    } else {
        if (blue_paper > red_paper) {
            black_paper = 1 - blue_paper;
        } else {
            black_paper = 1 - green_paper;
        }
    }
    if (black_paper < 1.0) {
        cyan_paper = (1 - red_paper - black_paper) / (1 - black_paper);
        magenta_paper = (1 - green_paper - black_paper) / (1 - black_paper);
        yellow_paper = (1 - blue_paper - black_paper) / (1 - black_paper);
    } else {
        cyan_paper = 0.0;
        magenta_paper = 0.0;
        yellow_paper = 0.0;
    }

    if (symbol->height == 0) {
        symbol->height = 50;
    }

    large_bar_count = 0;
    preset_height = 0.0;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(symbol->text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(local_text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218

219
220




221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237



238
239
240
241
242
243

244



245
246
247
248
249

250
251




252
253
254
255
256
257
258
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(symbol->text); i++) {
            if (latch == 1) {
                addon[r] = symbol->text[i];
                r++;
            }
            if (symbol->text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';

    if ((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) {
        plot_text = 0;
    }
    if (plot_text) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }
    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;

    /* Start writing the header */
    fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n");
    fprintf(feps, "%%%%Creator: Zint %s\n", ZINT_VERSION);
    if (ustrlen(symbol->text) != 0) {
        fprintf(feps, "%%%%Title: %s\n", symbol->text);
    } else {
        fprintf(feps, "%%%%Title: Zint Generated Symbol\n");
    }
    fprintf(feps, "%%%%Pages: 0\n");
    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int)ceil((symbol->width + xoffset + xoffset) * scaler), (int)ceil((symbol->height + textoffset + yoffset + yoffset) * scaler));
    } else {
        fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int)ceil((74.0F + xoffset + xoffset) * scaler), (int)ceil((72.0F + yoffset + yoffset) * scaler));
    }
    fprintf(feps, "%%%%EndComments\n");

    /* Definitions */
    fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n");
    fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n");

    fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n");
    fprintf(feps, "/TB { 2 copy } bind def\n");
    fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n");
    fprintf(feps, "/TE { pop pop } bind def\n");

    fprintf(feps, "newpath\n");

    /* Now the actual representation */

    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);




    fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler);

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        default_text_posn = 0.5 * scaler;
    } else {
        default_text_posn = (symbol->border_width + 0.5) * scaler;
    }

    if (symbol->symbology == BARCODE_MAXICODE) {
        /* Maxicode uses hexagons */
        float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my;


        textoffset = 0.0;
        if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler);
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler);
        }
        if ((symbol->output_options & BARCODE_BOX) != 0) {
            /* side bars */
            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler);
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler);
        }

        fprintf(feps, "TE\n");

        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);




        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        for (r = 0; r < symbol->rows; r++) {
            for (i = 0; i < symbol->width; i++) {
                if (module_is_set(symbol, r, i)) {
                    /* Dump a hexagon */







|

|


|






<
<
<
|










|
|





|

|






>








>
|
|
>
>
>
>
















>
|
>
>
>






>
|
>
>
>





>
|
|
>
>
>
>







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(local_text); i++) {
            if (latch == 1) {
                addon[r] = local_text[i];
                r++;
            }
            if (local_text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';




    if (ustrlen(local_text) != 0) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }
    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;

    /* Start writing the header */
    fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n");
    fprintf(feps, "%%%%Creator: Zint %s\n", ZINT_VERSION);
    if ((ustrlen(local_text) != 0) && (symbol->show_hrt != 0)) {
        fprintf(feps, "%%%%Title: %s\n", local_text);
    } else {
        fprintf(feps, "%%%%Title: Zint Generated Symbol\n");
    }
    fprintf(feps, "%%%%Pages: 0\n");
    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil((symbol->width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler));
    } else {
        fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil((74.0F + xoffset + xoffset) * scaler), (int) ceil((72.0F + yoffset + yoffset) * scaler));
    }
    fprintf(feps, "%%%%EndComments\n");

    /* Definitions */
    fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n");
    fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n");
    fprintf(feps, "/TD { newpath 0 360 arc fill } bind def\n");
    fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n");
    fprintf(feps, "/TB { 2 copy } bind def\n");
    fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n");
    fprintf(feps, "/TE { pop pop } bind def\n");

    fprintf(feps, "newpath\n");

    /* Now the actual representation */
    if ((symbol->output_options & CMYK_COLOUR) == 0) {
        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);
    } else {
        fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_paper, magenta_paper, yellow_paper, black_paper);
    }
    fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler);

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        default_text_posn = 0.5 * scaler;
    } else {
        default_text_posn = (symbol->border_width + 0.5) * scaler;
    }

    if (symbol->symbology == BARCODE_MAXICODE) {
        /* Maxicode uses hexagons */
        float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my;


        textoffset = 0.0;
        if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
            fprintf(feps, "TE\n");
            if ((symbol->output_options & CMYK_COLOUR) == 0) {
                fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
            } else {
                fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
            }
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler);
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler);
        }
        if ((symbol->output_options & BARCODE_BOX) != 0) {
            /* side bars */
            fprintf(feps, "TE\n");
            if ((symbol->output_options & CMYK_COLOUR) == 0) {
                fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
            } else {
                fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
            }
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler);
            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler);
        }

        fprintf(feps, "TE\n");
        if ((symbol->output_options & CMYK_COLOUR) == 0) {
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        } else {
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        }
        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler);
        for (r = 0; r < symbol->rows; r++) {
            for (i = 0; i < symbol->width; i++) {
                if (module_is_set(symbol, r, i)) {
                    /* Dump a hexagon */
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
















303

304




305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351



352
353
354
355
356
357
358
359
360
361
362
363

364



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421

422



423
424
425
426
427
428
429
430
431
432

433



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

507



508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

549



550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633



634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

722




723
724





725
726
727
728
729

730




731
732



733

734
735
736

737



738
739
740
741
742
743
744
745
746

747



748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768




769
770
771
            }
        }
    }

    if (symbol->symbology != BARCODE_MAXICODE) {
        /* everything else uses rectangles (or squares) */
        /* Works from the bottom of the symbol up */

        int addon_latch = 0;

        for (r = 0; r < symbol->rows; r++) {
            this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
            if (symbol->row_height[this_row] == 0) {
                row_height = large_bar_height;
            } else {
                row_height = symbol->row_height[this_row];
            }
            row_posn = 0;
            for (i = 0; i < r; i++) {
                if (symbol->row_height[symbol->rows - i - 1] == 0) {
                    row_posn += large_bar_height;
                } else {
                    row_posn += symbol->row_height[symbol->rows - i - 1];
                }
            }
            row_posn += (textoffset + yoffset);

















            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);




            fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler);
            i = 0;
            if (module_is_set(symbol, this_row, 0)) {
                latch = 1;
            } else {
                latch = 0;
            }

            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
                if ((addon_latch == 0) && (r == 0) && (i > main_width)) {
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                    fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler);
                    addon_text_posn = row_posn + row_height - 8.0;
                    addon_latch = 1;
                }
                if (latch == 1) {
                    /* a bar */
                    fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler);
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;

            } while (i < symbol->width);

        }
    }
    /* That's done the actual data area, everything else is human-friendly */

    xoffset += comp_offset;

    if (plot_text) {
        if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) ||
                (symbol->symbology == BARCODE_ISBNX)) {
            /* guard bar extensions and text formatting for EAN8 and EAN13 */
            switch (ustrlen(symbol->text)) {
                case 8: /* EAN-8 */
                case 11:
                case 14:
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                    fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler);
                    for (i = 0; i < 4; i++) {
                        textpart[i] = symbol->text[i];
                    }
                    textpart[4] = '\0';
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = 17;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(feps, " (%s) stringwidth\n", textpart);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", textpart);
                    fprintf(feps, "setmatrix\n");
                    for (i = 0; i < 4; i++) {
                        textpart[i] = symbol->text[i + 4];
                    }
                    textpart[4] = '\0';
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = 50;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(feps, " (%s) stringwidth\n", textpart);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", textpart);
                    fprintf(feps, "setmatrix\n");
                    textdone = 1;
                    switch (strlen(addon)) {
                        case 2:
                            fprintf(feps, "matrix currentmatrix\n");
                            fprintf(feps, "/Helvetica findfont\n");
                            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                            textpos = xoffset + 86;
                            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(feps, " (%s) stringwidth\n", addon);
                            fprintf(feps, "pop\n");
                            fprintf(feps, "-2 div 0 rmoveto\n");
                            fprintf(feps, " (%s) show\n", addon);
                            fprintf(feps, "setmatrix\n");
                            break;
                        case 5:
                            fprintf(feps, "matrix currentmatrix\n");
                            fprintf(feps, "/Helvetica findfont\n");
                            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                            textpos = xoffset + 100;
                            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(feps, " (%s) stringwidth\n", addon);
                            fprintf(feps, "pop\n");
                            fprintf(feps, "-2 div 0 rmoveto\n");
                            fprintf(feps, " (%s) show\n", addon);
                            fprintf(feps, "setmatrix\n");
                            break;
                    }

                    break;
                case 13: /* EAN 13 */
                case 16:
                case 19:
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                    fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler);
                    fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler);
                    textpart[0] = symbol->text[0];
                    textpart[1] = '\0';
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = -7;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(feps, " (%s) stringwidth\n", textpart);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", textpart);
                    fprintf(feps, "setmatrix\n");
                    for (i = 0; i < 6; i++) {
                        textpart[i] = symbol->text[i + 1];
                    }
                    textpart[6] = '\0';
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = 24;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(feps, " (%s) stringwidth\n", textpart);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", textpart);
                    fprintf(feps, "setmatrix\n");
                    for (i = 0; i < 6; i++) {
                        textpart[i] = symbol->text[i + 7];
                    }
                    textpart[6] = '\0';
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = 71;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(feps, " (%s) stringwidth\n", textpart);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", textpart);
                    fprintf(feps, "setmatrix\n");
                    textdone = 1;
                    switch (strlen(addon)) {
                        case 2:
                            fprintf(feps, "matrix currentmatrix\n");
                            fprintf(feps, "/Helvetica findfont\n");
                            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                            textpos = xoffset + 114;
                            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(feps, " (%s) stringwidth\n", addon);
                            fprintf(feps, "pop\n");
                            fprintf(feps, "-2 div 0 rmoveto\n");
                            fprintf(feps, " (%s) show\n", addon);
                            fprintf(feps, "setmatrix\n");
                            break;
                        case 5:
                            fprintf(feps, "matrix currentmatrix\n");
                            fprintf(feps, "/Helvetica findfont\n");
                            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                            textpos = xoffset + 128;
                            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(feps, " (%s) stringwidth\n", addon);
                            fprintf(feps, "pop\n");
                            fprintf(feps, "-2 div 0 rmoveto\n");
                            fprintf(feps, " (%s) show\n", addon);
                            fprintf(feps, "setmatrix\n");
                            break;
                    }
                    break;

            }
        }

        if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
            /* guard bar extensions and text formatting for UPCA */
            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



            fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
            latch = 1;

            i = 0 + comp_offset;
            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
                if (latch == 1) {
                    /* a bar */
                    fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler);
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;
            } while (i < 11 + comp_offset);
            fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
            latch = 1;
            i = 85 + comp_offset;
            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
                if (latch == 1) {
                    /* a bar */
                    fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler);
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;
            } while (i < 96 + comp_offset);
            textpart[0] = symbol->text[0];
            textpart[1] = '\0';
            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
            textpos = -5;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            for (i = 0; i < 5; i++) {
                textpart[i] = symbol->text[i + 1];
            }
            textpart[5] = '\0';
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
            textpos = 27;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            for (i = 0; i < 5; i++) {
                textpart[i] = symbol->text[i + 6];
            }
            textpart[6] = '\0';
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
            textpos = 68;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            textpart[0] = symbol->text[11];
            textpart[1] = '\0';
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
            textpos = 100;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            textdone = 1;
            switch (strlen(addon)) {
                case 2:
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = xoffset + 116;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(feps, " (%s) stringwidth\n", addon);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", addon);
                    fprintf(feps, "setmatrix\n");
                    break;
                case 5:
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = xoffset + 130;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(feps, " (%s) stringwidth\n", addon);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", addon);
                    fprintf(feps, "setmatrix\n");
                    break;
            }

        }

        if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
            /* guard bar extensions and text formatting for UPCE */
            fprintf(feps, "TE\n");

            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



            fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
            fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler);
            textpart[0] = symbol->text[0];
            textpart[1] = '\0';
            fprintf(feps, "TE\n");
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
            textpos = -5;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            for (i = 0; i < 6; i++) {
                textpart[i] = symbol->text[i + 1];
            }
            textpart[6] = '\0';
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
            textpos = 24;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            textpart[0] = symbol->text[7];
            textpart[1] = '\0';
            fprintf(feps, "matrix currentmatrix\n");
            fprintf(feps, "/Helvetica findfont\n");
            fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
            textpos = 55;
            fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(feps, " (%s) stringwidth\n", textpart);
            fprintf(feps, "pop\n");
            fprintf(feps, "-2 div 0 rmoveto\n");
            fprintf(feps, " (%s) show\n", textpart);
            fprintf(feps, "setmatrix\n");
            textdone = 1;
            switch (strlen(addon)) {
                case 2:
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = xoffset + 70;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(feps, " (%s) stringwidth\n", addon);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", addon);
                    fprintf(feps, "setmatrix\n");
                    break;
                case 5:
                    fprintf(feps, "matrix currentmatrix\n");
                    fprintf(feps, "/Helvetica findfont\n");
                    fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                    textpos = xoffset + 84;
                    fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(feps, " (%s) stringwidth\n", addon);
                    fprintf(feps, "pop\n");
                    fprintf(feps, "-2 div 0 rmoveto\n");
                    fprintf(feps, " (%s) show\n", addon);
                    fprintf(feps, "setmatrix\n");
                    break;
            }

        }
    } /* if (plot_text) */

    xoffset -= comp_offset;

    switch (symbol->symbology) {
        case BARCODE_MAXICODE:
            /* Do nothing! (It's already been done) */
            break;
        default:
            if ((symbol->output_options & BARCODE_BIND) != 0) {
                if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                    /* row binding */
                    fprintf(feps, "TE\n");

                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);




                    for (r = 1; r < symbol->rows; r++) {
                        fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler);





                    }
                }
            }
            if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
                fprintf(feps, "TE\n");

                fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);




                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler);
                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler);



            }

            if ((symbol->output_options & BARCODE_BOX) != 0) {
                /* side bars */
                fprintf(feps, "TE\n");

                fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler);
                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler);
            }
            break;
    }

    /* Put the human readable text at the bottom */
    if (plot_text && (textdone == 0)) {
        fprintf(feps, "TE\n");

        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);



        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = symbol->width / 2.0;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", symbol->text);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", symbol->text);
        fprintf(feps, "setmatrix\n");
    }
    fprintf(feps, "\nshowpage\n");

    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(feps);
    } else {
        fclose(feps);
    }

    if (locale)
        setlocale(LC_ALL, locale);





    return error_number;
}







>



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
|
|
|
|
|
|
|

|
|
|
|
|
|
|
>
|
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|

|
>






<
|
|
|
|
|
|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
>

>
>
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
>

>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
<








|



>
|
>
>
>
>
|
|
>
>
>
>
>



|

>
|
>
>
>
>
|
|
>
>
>
|
>
|


>
|
>
>
>







|

>
|
>
>
>





|


|












>
>
>
>



396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
            }
        }
    }

    if (symbol->symbology != BARCODE_MAXICODE) {
        /* everything else uses rectangles (or squares) */
        /* Works from the bottom of the symbol up */

        int addon_latch = 0;

        for (r = 0; r < symbol->rows; r++) {
            this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
            if (symbol->row_height[this_row] == 0) {
                row_height = large_bar_height;
            } else {
                row_height = symbol->row_height[this_row];
            }
            row_posn = 0;
            for (i = 0; i < r; i++) {
                if (symbol->row_height[symbol->rows - i - 1] == 0) {
                    row_posn += large_bar_height;
                } else {
                    row_posn += symbol->row_height[symbol->rows - i - 1];
                }
            }
            row_posn += (textoffset + yoffset);

            if ((symbol->output_options & BARCODE_DOTTY_MODE) != 0) {
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }

                /* Use dots instead of squares */
                for (i = 0; i < symbol->width; i++) {
                    if (module_is_set(symbol, this_row, i)) {
                        fprintf(feps, "%.2f %.2f %.2f TD\n", ((i + xoffset) * scaler) + (scaler / 2.0), (row_posn * scaler) + (scaler / 2.0), (symbol->dot_size / 2.0) * scaler);
                    }
                }
            } else {
                /* Normal mode, with rectangles */

                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }

                fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler);
                i = 0;
                if (module_is_set(symbol, this_row, 0)) {
                    latch = 1;
                } else {
                    latch = 0;
                }

                do {
                    block_width = 0;
                    do {
                        block_width++;
                    } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
                    if ((addon_latch == 0) && (r == 0) && (i > main_width)) {
                        fprintf(feps, "TE\n");
                        if ((symbol->output_options & CMYK_COLOUR) == 0) {
                            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                        } else {
                            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                        }
                        fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler);
                        addon_text_posn = row_posn + row_height - 8.0;
                        addon_latch = 1;
                    }
                    if (latch == 1) {
                        /* a bar */
                        fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler);
                        latch = 0;
                    } else {
                        /* a space */
                        latch = 1;
                    }
                    i += block_width;

                } while (i < symbol->width);
            }
        }
    }
    /* That's done the actual data area, everything else is human-friendly */

    xoffset += comp_offset;


    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) ||
            (symbol->symbology == BARCODE_ISBNX)) {
        /* guard bar extensions and text formatting for EAN8 and EAN13 */
        switch (ustrlen(local_text)) {
            case 8: /* EAN-8 */
            case 11:
            case 14:
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler);
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i];
                }
                textpart[4] = '\0';
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = 17;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(feps, " (%s) stringwidth\n", textpart);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", textpart);
                fprintf(feps, "setmatrix\n");
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i + 4];
                }
                textpart[4] = '\0';
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = 50;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(feps, " (%s) stringwidth\n", textpart);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", textpart);
                fprintf(feps, "setmatrix\n");
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        fprintf(feps, "matrix currentmatrix\n");
                        fprintf(feps, "/Helvetica findfont\n");
                        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                        textpos = xoffset + 86;
                        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(feps, " (%s) stringwidth\n", addon);
                        fprintf(feps, "pop\n");
                        fprintf(feps, "-2 div 0 rmoveto\n");
                        fprintf(feps, " (%s) show\n", addon);
                        fprintf(feps, "setmatrix\n");
                        break;
                    case 5:
                        fprintf(feps, "matrix currentmatrix\n");
                        fprintf(feps, "/Helvetica findfont\n");
                        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                        textpos = xoffset + 100;
                        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(feps, " (%s) stringwidth\n", addon);
                        fprintf(feps, "pop\n");
                        fprintf(feps, "-2 div 0 rmoveto\n");
                        fprintf(feps, " (%s) show\n", addon);
                        fprintf(feps, "setmatrix\n");
                        break;
                }

                break;
            case 13: /* EAN 13 */
            case 16:
            case 19:
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler);
                fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler);
                textpart[0] = local_text[0];
                textpart[1] = '\0';
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = -7;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(feps, " (%s) stringwidth\n", textpart);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", textpart);
                fprintf(feps, "setmatrix\n");
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 1];
                }
                textpart[6] = '\0';
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = 24;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(feps, " (%s) stringwidth\n", textpart);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", textpart);
                fprintf(feps, "setmatrix\n");
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 7];
                }
                textpart[6] = '\0';
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = 71;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(feps, " (%s) stringwidth\n", textpart);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", textpart);
                fprintf(feps, "setmatrix\n");
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        fprintf(feps, "matrix currentmatrix\n");
                        fprintf(feps, "/Helvetica findfont\n");
                        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                        textpos = xoffset + 114;
                        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(feps, " (%s) stringwidth\n", addon);
                        fprintf(feps, "pop\n");
                        fprintf(feps, "-2 div 0 rmoveto\n");
                        fprintf(feps, " (%s) show\n", addon);
                        fprintf(feps, "setmatrix\n");
                        break;
                    case 5:
                        fprintf(feps, "matrix currentmatrix\n");
                        fprintf(feps, "/Helvetica findfont\n");
                        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                        textpos = xoffset + 128;
                        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(feps, " (%s) stringwidth\n", addon);
                        fprintf(feps, "pop\n");
                        fprintf(feps, "-2 div 0 rmoveto\n");
                        fprintf(feps, " (%s) show\n", addon);
                        fprintf(feps, "setmatrix\n");
                        break;
                }
                break;

        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        /* guard bar extensions and text formatting for UPCA */
        fprintf(feps, "TE\n");
        if ((symbol->output_options & CMYK_COLOUR) == 0) {
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        } else {
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        }
        fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
        latch = 1;

        i = 0 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 11 + comp_offset);
        fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
        latch = 1;
        i = 85 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 96 + comp_offset);
        textpart[0] = local_text[0];
        textpart[1] = '\0';
        fprintf(feps, "TE\n");
        if ((symbol->output_options & CMYK_COLOUR) == 0) {
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        } else {
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        }
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = -5;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[5] = '\0';
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
        textpos = 27;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 6];
        }
        textpart[6] = '\0';
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
        textpos = 68;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        textpart[0] = local_text[11];
        textpart[1] = '\0';
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = 100;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = xoffset + 116;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(feps, " (%s) stringwidth\n", addon);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", addon);
                fprintf(feps, "setmatrix\n");
                break;
            case 5:
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = xoffset + 130;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(feps, " (%s) stringwidth\n", addon);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", addon);
                fprintf(feps, "setmatrix\n");
                break;
        }

    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        /* guard bar extensions and text formatting for UPCE */
        fprintf(feps, "TE\n");
        if ((symbol->output_options & CMYK_COLOUR) == 0) {
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        } else {
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        }
        fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler);
        fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler);
        textpart[0] = local_text[0];
        textpart[1] = '\0';
        fprintf(feps, "TE\n");
        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = -5;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        for (i = 0; i < 6; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[6] = '\0';
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
        textpos = 24;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        textpart[0] = local_text[7];
        textpart[1] = '\0';
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = 55;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", textpart);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", textpart);
        fprintf(feps, "setmatrix\n");
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = xoffset + 70;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(feps, " (%s) stringwidth\n", addon);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", addon);
                fprintf(feps, "setmatrix\n");
                break;
            case 5:
                fprintf(feps, "matrix currentmatrix\n");
                fprintf(feps, "/Helvetica findfont\n");
                fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler);
                textpos = xoffset + 84;
                fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(feps, " (%s) stringwidth\n", addon);
                fprintf(feps, "pop\n");
                fprintf(feps, "-2 div 0 rmoveto\n");
                fprintf(feps, " (%s) show\n", addon);
                fprintf(feps, "setmatrix\n");
                break;
        }

    }


    xoffset -= comp_offset;

    switch (symbol->symbology) {
        case BARCODE_MAXICODE:
            /* Do nothing! (It's already been done) */
            break;
        default:
            if (symbol->output_options & BARCODE_BIND) {
                if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                    /* row binding */
                    fprintf(feps, "TE\n");
                    if ((symbol->output_options & CMYK_COLOUR) == 0) {
                        fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                    } else {
                        fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                    }
                    if (symbol->symbology != BARCODE_CODABLOCKF) {
                        for (r = 1; r < symbol->rows; r++) {
                            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler);
                        }
                    } else {
                        for (r = 1; r < symbol->rows; r++) {
                            fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, (xoffset + 11) * scaler, (symbol->width - 25) * scaler);
                        }
                    }
                }
            }
            if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                if (symbol->symbology != BARCODE_CODABLOCKF) {
                    fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler);
                    fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler);
                } else {
                    fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, xoffset * scaler, symbol->width * scaler);
                    fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, xoffset * scaler, symbol->width * scaler);
                }
            }
            if (symbol->output_options & BARCODE_BOX) {
                /* side bars */
                fprintf(feps, "TE\n");
                if ((symbol->output_options & CMYK_COLOUR) == 0) {
                    fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
                } else {
                    fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
                }
                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler);
                fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler);
            }
            break;
    }

    /* Put the human readable text at the bottom */
    if ((textdone == 0) && (ustrlen(local_text))) {
        fprintf(feps, "TE\n");
        if ((symbol->output_options & CMYK_COLOUR) == 0) {
            fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
        } else {
            fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
        }
        fprintf(feps, "matrix currentmatrix\n");
        fprintf(feps, "/Helvetica findfont\n");
        fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler);
        textpos = symbol->width / 2.0;
        fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(feps, " (%s) stringwidth\n", local_text);
        fprintf(feps, "pop\n");
        fprintf(feps, "-2 div 0 rmoveto\n");
        fprintf(feps, " (%s) show\n", local_text);
        fprintf(feps, "setmatrix\n");
    }
    fprintf(feps, "\nshowpage\n");

    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(feps);
    } else {
        fclose(feps);
    }

    if (locale)
        setlocale(LC_ALL, locale);

#ifdef _MSC_VER
    free(local_text);
#endif

    return error_number;
}
Changes to jni/zint/backend/qr.c.
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138




139
140
141
142
143
144
145
                }
            }
        }
    }
}

/* Make an estimate (worst case scenario) of how long the binary string will be */
int estimate_binary_length(char mode[], int length, int gs1) {
    int i, count = 0;
    char current = 0;
    int a_count = 0;
    int n_count = 0;

    if (gs1) {
        count += 4;
    }





    for (i = 0; i < length; i++) {
        if (mode[i] != current) {
            switch (mode[i]) {
                case 'K': count += 12 + 4;
                    current = 'K';
                    break;







|








>
>
>
>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
                }
            }
        }
    }
}

/* Make an estimate (worst case scenario) of how long the binary string will be */
int estimate_binary_length(char mode[], int length, int gs1, int eci) {
    int i, count = 0;
    char current = 0;
    int a_count = 0;
    int n_count = 0;

    if (gs1) {
        count += 4;
    }
    
    if (eci != 3) {
        count += 12;
    }

    for (i = 0; i < length; i++) {
        if (mode[i] != current) {
            switch (mode[i]) {
                case 'K': count += 12 + 4;
                    current = 'K';
                    break;
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212





213
214
215
216
217
218
219
static void qr_bscan(char *binary, int data, int h) {
    for (; h; h >>= 1) {
        strcat(binary, data & h ? "1" : "0");
    }
}

/* Convert input data to a binary stream and add padding */
void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen) {
    int position = 0, debug = 0;
    int short_data_block_length, i, scheme = 1;
    char data_block, padbits;
    int current_binlen, current_bytes;
    int toggle, percent;

#ifndef _MSC_VER
    char binary[est_binlen + 12];
#else
    char* binary = (char *) _alloca(est_binlen + 12);
#endif
    strcpy(binary, "");

    if (gs1) {
        strcat(binary, "0101"); /* FNC1 */
    }






    if (version <= 9) {
        scheme = 1;
    } else if ((version >= 10) && (version <= 26)) {
        scheme = 2;
    } else if (version >= 27) {
        scheme = 3;







|
















>
>
>
>
>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
static void qr_bscan(char *binary, int data, int h) {
    for (; h; h >>= 1) {
        strcat(binary, data & h ? "1" : "0");
    }
}

/* Convert input data to a binary stream and add padding */
void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int eci, int est_binlen) {
    int position = 0, debug = 0;
    int short_data_block_length, i, scheme = 1;
    char data_block, padbits;
    int current_binlen, current_bytes;
    int toggle, percent;

#ifndef _MSC_VER
    char binary[est_binlen + 12];
#else
    char* binary = (char *) _alloca(est_binlen + 12);
#endif
    strcpy(binary, "");

    if (gs1) {
        strcat(binary, "0101"); /* FNC1 */
    }
    
    if (eci != 3) {
        strcat(binary, "0111"); /* ECI */
        qr_bscan(binary, eci, 0x80);
    }

    if (version <= 9) {
        scheme = 1;
    } else if ((version >= 10) && (version <= 26)) {
        scheme = 2;
    } else if (version >= 27) {
        scheme = 3;
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
}

int apply_bitmask(unsigned char *grid, int size, int ecc_level) {
    int x, y;
    unsigned char p;
    int pattern, penalty[8];
    int best_val, best_pattern;
    int bit;

#ifndef _MSC_VER
    unsigned char mask[size * size];
    unsigned char eval[size * size];
#else
    unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
    unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));







<







1093
1094
1095
1096
1097
1098
1099

1100
1101
1102
1103
1104
1105
1106
}

int apply_bitmask(unsigned char *grid, int size, int ecc_level) {
    int x, y;
    unsigned char p;
    int pattern, penalty[8];
    int best_val, best_pattern;


#ifndef _MSC_VER
    unsigned char mask[size * size];
    unsigned char eval[size * size];
#else
    unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
    unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
    write_log("choosed pattern:");
    write_log(str);
#endif

    /* Apply mask */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            bit = 0;
            switch (best_pattern) {
                case 0: if (mask[(y * size) + x] & 0x01) {
                        bit = 1;
                    }
                    break;
                case 1: if (mask[(y * size) + x] & 0x02) {
                        bit = 1;
                    }
                    break;
                case 2: if (mask[(y * size) + x] & 0x04) {
                        bit = 1;
                    }
                    break;
                case 3: if (mask[(y * size) + x] & 0x08) {
                        bit = 1;
                    }
                    break;
                case 4: if (mask[(y * size) + x] & 0x10) {
                        bit = 1;
                    }
                    break;
                case 5: if (mask[(y * size) + x] & 0x20) {
                        bit = 1;
                    }
                    break;
                case 6: if (mask[(y * size) + x] & 0x40) {
                        bit = 1;
                    }
                    break;
                case 7: if (mask[(y * size) + x] & 0x80) {
                        bit = 1;
                    }
                    break;
            }
            if (bit == 1) {
                if (grid[(y * size) + x] & 0x01) {
                    grid[(y * size) + x] = 0x00;
                } else {
                    grid[(y * size) + x] = 0x01;
                }
            }
        }







<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1178
1179
1180
1181
1182
1183
1184


1185

































1186
1187
1188
1189
1190
1191
1192
    write_log("choosed pattern:");
    write_log(str);
#endif

    /* Apply mask */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {


            if (mask[(y * size) + x] & (0x01 << best_pattern)) {

































                if (grid[(y * size) + x] & 0x01) {
                    grid[(y * size) + x] = 0x00;
                } else {
                    grid[(y * size) + x] = 0x01;
                }
            }
        }
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438




1439
1440
1441
1442
1443
1444
1445
    do {
        count++;
    } while (((i + count) < inputLength) && (inputMode[i + count] == mode));

    return count;
}

int getBinaryLength(int version, char inputMode[], int inputData[], int inputLength, int gs1) {
    /* Calculate the actual bitlength of the proposed binary string */
    char currentMode;
    int i, j;
    int count = 0;

    applyOptimisation(version, inputMode, inputLength);

    currentMode = ' '; // Null

    if (gs1 == 1) {
        count += 4;
    }





    for (i = 0; i < inputLength; i++) {
        if (inputMode[i] != currentMode) {
            count += 4;
            switch (inputMode[i]) {
                case 'K':
                    count += tribus(version, 8, 10, 12);







|












>
>
>
>







1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
    do {
        count++;
    } while (((i + count) < inputLength) && (inputMode[i + count] == mode));

    return count;
}

int getBinaryLength(int version, char inputMode[], int inputData[], int inputLength, int gs1, int eci) {
    /* Calculate the actual bitlength of the proposed binary string */
    char currentMode;
    int i, j;
    int count = 0;

    applyOptimisation(version, inputMode, inputLength);

    currentMode = ' '; // Null

    if (gs1 == 1) {
        count += 4;
    }
    
    if (eci != 3) {
        count += 12;
    }

    for (i = 0; i < inputLength; i++) {
        if (inputMode[i] != currentMode) {
            count += 4;
            switch (inputMode[i]) {
                case 'K':
                    count += tribus(version, 8, 10, 12);
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
    int* utfdata = (int *) _alloca((length + 1) * sizeof (int));
    int* jisdata = (int *) _alloca((length + 1) * sizeof (int));
    char* mode = (char *) _alloca(length + 1);
#endif

    gs1 = (symbol->input_mode == GS1_MODE);

    switch (symbol->input_mode) {
        case DATA_MODE:
            for (i = 0; i < length; i++) {
                jisdata[i] = (int) source[i];
            }
            break;
        default:
            /* Convert Unicode input to Shift-JIS */
            error_number = utf8toutf16(symbol, source, utfdata, &length);
            if (error_number != 0) {
                return error_number;
            }

            for (i = 0; i < length; i++) {
                if (utfdata[i] <= 0xff) {
                    jisdata[i] = utfdata[i];
                } else {
                    j = 0;
                    glyph = 0;
                    do {
                        if (sjis_lookup[j * 2] == utfdata[i]) {
                            glyph = sjis_lookup[(j * 2) + 1];
                        }
                        j++;
                    } while ((j < 6843) && (glyph == 0));
                    if (glyph == 0) {
                        strcpy(symbol->errtxt, "Invalid character in input data");
                        return ZINT_ERROR_INVALID_DATA;
                    }
                    jisdata[i] = glyph;
                }
            }
            break;
    }

    define_mode(mode, jisdata, length, gs1);
    est_binlen = estimate_binary_length(mode, length, gs1);

    ecc_level = LEVEL_L;
    max_cw = 2956;
    if ((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) {
        switch (symbol->option_1) {
            case 1: ecc_level = LEVEL_L;
                max_cw = 2956;







|
<
|
|
|
|
<
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<



|







1485
1486
1487
1488
1489
1490
1491
1492

1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521

1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
    int* utfdata = (int *) _alloca((length + 1) * sizeof (int));
    int* jisdata = (int *) _alloca((length + 1) * sizeof (int));
    char* mode = (char *) _alloca(length + 1);
#endif

    gs1 = (symbol->input_mode == GS1_MODE);

    if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {

        for (i = 0; i < length; i++) {
            jisdata[i] = (int) source[i];
        }
    } else {

        /* Convert Unicode input to Shift-JIS */
        error_number = utf8toutf16(symbol, source, utfdata, &length);
        if (error_number != 0) {
            return error_number;
        }

        for (i = 0; i < length; i++) {
            if (utfdata[i] <= 0xff) {
                jisdata[i] = utfdata[i];
            } else {
                j = 0;
                glyph = 0;
                do {
                    if (sjis_lookup[j * 2] == utfdata[i]) {
                        glyph = sjis_lookup[(j * 2) + 1];
                    }
                    j++;
                } while ((j < 6843) && (glyph == 0));
                if (glyph == 0) {
                    strcpy(symbol->errtxt, "Invalid character in input data (E60)");
                    return ZINT_ERROR_INVALID_DATA;
                }
                jisdata[i] = glyph;
            }
        }

    }

    define_mode(mode, jisdata, length, gs1);
    est_binlen = estimate_binary_length(mode, length, gs1, symbol->eci);

    ecc_level = LEVEL_L;
    max_cw = 2956;
    if ((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) {
        switch (symbol->option_1) {
            case 1: ecc_level = LEVEL_L;
                max_cw = 2956;
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
            case 4: ecc_level = LEVEL_H;
                max_cw = 1276;
                break;
        }
    }

    if (est_binlen > (8 * max_cw)) {
        strcpy(symbol->errtxt, "Input too long for selected error correction level");
        return ZINT_ERROR_TOO_LONG;
    }

    autosize = 40;
    for (i = 39; i >= 0; i--) {
        switch (ecc_level) {
            case LEVEL_L:







|







1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
            case 4: ecc_level = LEVEL_H;
                max_cw = 1276;
                break;
        }
    }

    if (est_binlen > (8 * max_cw)) {
        strcpy(symbol->errtxt, "Input too long for selected error correction level (E61)");
        return ZINT_ERROR_TOO_LONG;
    }

    autosize = 40;
    for (i = 39; i >= 0; i--) {
        switch (ecc_level) {
            case LEVEL_L:
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

    do {
        if (autosize == 1) {
            canShrink = 0;
        } else {
            if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
                // Length of binary needed to encode the data in the smaller symbol is different, recalculate
                est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1);
            }

            switch (ecc_level) {
                case LEVEL_L:
                    if ((8 * qr_data_codewords_L[autosize - 2]) < est_binlen) {
                        canShrink = 0;
                    }







|







1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593

    do {
        if (autosize == 1) {
            canShrink = 0;
        } else {
            if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
                // Length of binary needed to encode the data in the smaller symbol is different, recalculate
                est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1, symbol->eci);
            }

            switch (ecc_level) {
                case LEVEL_L:
                    if ((8 * qr_data_codewords_L[autosize - 2]) < est_binlen) {
                        canShrink = 0;
                    }
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666

            if (canShrink == 1) {
                // Optimisation worked - data will fit in a smaller symbol
                autosize--;
            } else {
                // Data did not fit in the smaller symbol, revert to original size
                if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
                    est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1);
                }
            }
        }
    } while (canShrink == 1);

    version = autosize;

    if ((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) {
        /* If the user has selected a larger symbol than the smallest available,
         then use the size the user has selected, and re-optimise for this
         symbol size.
         */
        if (symbol->option_2 > version) {
            version = symbol->option_2;
            est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1);
        }
    }

    /* Ensure maxium error correction capacity */
    if (est_binlen <= qr_data_codewords_M[version - 1]) {
        ecc_level = LEVEL_M;
    }







|














|







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

            if (canShrink == 1) {
                // Optimisation worked - data will fit in a smaller symbol
                autosize--;
            } else {
                // Data did not fit in the smaller symbol, revert to original size
                if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
                    est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1, symbol->eci);
                }
            }
        }
    } while (canShrink == 1);

    version = autosize;

    if ((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) {
        /* If the user has selected a larger symbol than the smallest available,
         then use the size the user has selected, and re-optimise for this
         symbol size.
         */
        if (symbol->option_2 > version) {
            version = symbol->option_2;
            est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1, symbol->eci);
        }
    }

    /* Ensure maxium error correction capacity */
    if (est_binlen <= qr_data_codewords_M[version - 1]) {
        ecc_level = LEVEL_M;
    }
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
    int datastream[target_binlen + 1];
    int fullstream[qr_total_codewords[version - 1] + 1];
#else
    datastream = (int *) _alloca((target_binlen + 1) * sizeof (int));
    fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int));
#endif

    qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen);
    add_ecc(fullstream, datastream, version, target_binlen, blocks);

    size = qr_sizes[version - 1];
#ifndef _MSC_VER
    unsigned char grid[size * size];
#else
    grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));







|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
    int datastream[target_binlen + 1];
    int fullstream[qr_total_codewords[version - 1] + 1];
#else
    datastream = (int *) _alloca((target_binlen + 1) * sizeof (int));
    fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int));
#endif

    qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, symbol->eci, est_binlen);
    add_ecc(fullstream, datastream, version, target_binlen, blocks);

    size = qr_sizes[version - 1];
#ifndef _MSC_VER
    unsigned char grid[size * size];
#else
    grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
                break;
        }

    } while (i < length);
}

void micro_qr_m1(char binary_data[]) {
    int i, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[4], ecc_blocks[3];

    bits_total = 20;
    latch = 0;








|







2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
                break;
        }

    } while (i < length);
}

void micro_qr_m1(char binary_data[]) {
    int i, j, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[4], ecc_blocks[3];

    bits_total = 20;
    latch = 0;

2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207

    data_codewords = 3;
    ecc_codewords = 2;

    /* Copy data into codewords */
    for (i = 0; i < (data_codewords - 1); i++) {
        data_blocks[i] = 0;
        if (binary_data[i * 8] == '1') {
            data_blocks[i] += 0x80;
        }
        if (binary_data[(i * 8) + 1] == '1') {
            data_blocks[i] += 0x40;
        }
        if (binary_data[(i * 8) + 2] == '1') {
            data_blocks[i] += 0x20;
        }
        if (binary_data[(i * 8) + 3] == '1') {
            data_blocks[i] += 0x10;
        }
        if (binary_data[(i * 8) + 4] == '1') {
            data_blocks[i] += 0x08;
        }
        if (binary_data[(i * 8) + 5] == '1') {
            data_blocks[i] += 0x04;
        }
        if (binary_data[(i * 8) + 6] == '1') {
            data_blocks[i] += 0x02;
        }
        if (binary_data[(i * 8) + 7] == '1') {
            data_blocks[i] += 0x01;
        }
    }
    data_blocks[2] = 0;
    if (binary_data[16] == '1') {
        data_blocks[2] += 0x08;
    }
    if (binary_data[17] == '1') {
        data_blocks[2] += 0x04;
    }
    if (binary_data[18] == '1') {
        data_blocks[2] += 0x02;
    }
    if (binary_data[19] == '1') {
        data_blocks[2] += 0x01;
    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);
    rs_free();

    /* Add Reed-Solomon codewords to binary data */
    for (i = 0; i < ecc_codewords; i++) {
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }
}

void micro_qr_m2(char binary_data[], int ecc_mode) {
    int i, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[6], ecc_blocks[7];

    latch = 0;

    if (ecc_mode == LEVEL_L) {







<
|
<
|
|
|
<
<

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
<
|
|
|
<
<
<
<
<















|







2115
2116
2117
2118
2119
2120
2121

2122

2123
2124
2125


2126


2127













2128

2129

2130
2131
2132





2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155

    data_codewords = 3;
    ecc_codewords = 2;

    /* Copy data into codewords */
    for (i = 0; i < (data_codewords - 1); i++) {
        data_blocks[i] = 0;

        for (j = 0; j < 8; j++) {

            if (binary_data[(i * 8) + j] == '1') {
                data_blocks[i] += 0x80 >> j;
            }


        }


    }













    data_blocks[2] = 0;

    for (j = 0; j < 4; j++) {

        if (binary_data[16 + j] == '1') {
            data_blocks[2] += 0x08 >> j;
        }





    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);
    rs_free();

    /* Add Reed-Solomon codewords to binary data */
    for (i = 0; i < ecc_codewords; i++) {
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }
}

void micro_qr_m2(char binary_data[], int ecc_mode) {
    int i, j, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[6], ecc_blocks[7];

    latch = 0;

    if (ecc_mode == LEVEL_L) {
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
        data_codewords = 4;
        ecc_codewords = 6;
    }

    /* Copy data into codewords */
    for (i = 0; i < data_codewords; i++) {
        data_blocks[i] = 0;
        if (binary_data[i * 8] == '1') {
            data_blocks[i] += 0x80;
        }
        if (binary_data[(i * 8) + 1] == '1') {
            data_blocks[i] += 0x40;
        }
        if (binary_data[(i * 8) + 2] == '1') {
            data_blocks[i] += 0x20;
        }
        if (binary_data[(i * 8) + 3] == '1') {
            data_blocks[i] += 0x10;
        }
        if (binary_data[(i * 8) + 4] == '1') {
            data_blocks[i] += 0x08;
        }
        if (binary_data[(i * 8) + 5] == '1') {
            data_blocks[i] += 0x04;
        }
        if (binary_data[(i * 8) + 6] == '1') {
            data_blocks[i] += 0x02;
        }
        if (binary_data[(i * 8) + 7] == '1') {
            data_blocks[i] += 0x01;
        }
    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);
    rs_free();

    /* Add Reed-Solomon codewords to binary data */
    for (i = 0; i < ecc_codewords; i++) {
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }

    return;
}

void micro_qr_m3(char binary_data[], int ecc_mode) {
    int i, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[12], ecc_blocks[9];

    latch = 0;

    if (ecc_mode == LEVEL_L) {







<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















|







2196
2197
2198
2199
2200
2201
2202


2203

2204

2205
2206
2207














2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
        data_codewords = 4;
        ecc_codewords = 6;
    }

    /* Copy data into codewords */
    for (i = 0; i < data_codewords; i++) {
        data_blocks[i] = 0;


        

        for (j = 0; j < 8; j++) {

            if (binary_data[(i * 8) + j] == '1') {
                data_blocks[i] += 0x80 >> j;
            }














        }
    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);
    rs_free();

    /* Add Reed-Solomon codewords to binary data */
    for (i = 0; i < ecc_codewords; i++) {
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }

    return;
}

void micro_qr_m3(char binary_data[], int ecc_mode) {
    int i, j, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[12], ecc_blocks[9];

    latch = 0;

    if (ecc_mode == LEVEL_L) {
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
        data_codewords = 9;
        ecc_codewords = 8;
    }

    /* Copy data into codewords */
    for (i = 0; i < (data_codewords - 1); i++) {
        data_blocks[i] = 0;
        if (binary_data[i * 8] == '1') {
            data_blocks[i] += 0x80;
        }
        if (binary_data[(i * 8) + 1] == '1') {
            data_blocks[i] += 0x40;
        }
        if (binary_data[(i * 8) + 2] == '1') {
            data_blocks[i] += 0x20;
        }
        if (binary_data[(i * 8) + 3] == '1') {
            data_blocks[i] += 0x10;
        }
        if (binary_data[(i * 8) + 4] == '1') {
            data_blocks[i] += 0x08;
        }
        if (binary_data[(i * 8) + 5] == '1') {
            data_blocks[i] += 0x04;
        }
        if (binary_data[(i * 8) + 6] == '1') {
            data_blocks[i] += 0x02;
        }
        if (binary_data[(i * 8) + 7] == '1') {
            data_blocks[i] += 0x01;
        }
    }

    if (ecc_mode == LEVEL_L) {
        data_blocks[10] = 0;
        if (binary_data[80] == '1') {
            data_blocks[10] += 0x08;







<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2288
2289
2290
2291
2292
2293
2294


2295

2296

2297
2298
2299














2300
2301
2302
2303
2304
2305
2306
        data_codewords = 9;
        ecc_codewords = 8;
    }

    /* Copy data into codewords */
    for (i = 0; i < (data_codewords - 1); i++) {
        data_blocks[i] = 0;


        

        for (j = 0; j < 8; j++) {

            if (binary_data[(i * 8) + j] == '1') {
                data_blocks[i] += 0x80 >> j;
            }














        }
    }

    if (ecc_mode == LEVEL_L) {
        data_blocks[10] = 0;
        if (binary_data[80] == '1') {
            data_blocks[10] += 0x08;
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }

    return;
}

void micro_qr_m4(char binary_data[], int ecc_mode) {
    int i, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[17], ecc_blocks[15];

    latch = 0;

    if (ecc_mode == LEVEL_L) {







|







2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
        qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
    }

    return;
}

void micro_qr_m4(char binary_data[], int ecc_mode) {
    int i, j, latch;
    int bits_total, bits_left, remainder;
    int data_codewords, ecc_codewords;
    unsigned char data_blocks[17], ecc_blocks[15];

    latch = 0;

    if (ecc_mode == LEVEL_L) {
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
        data_codewords = 10;
        ecc_codewords = 14;
    }

    /* Copy data into codewords */
    for (i = 0; i < data_codewords; i++) {
        data_blocks[i] = 0;
        if (binary_data[i * 8] == '1') {
            data_blocks[i] += 0x80;
        }
        if (binary_data[(i * 8) + 1] == '1') {
            data_blocks[i] += 0x40;
        }
        if (binary_data[(i * 8) + 2] == '1') {
            data_blocks[i] += 0x20;
        }
        if (binary_data[(i * 8) + 3] == '1') {
            data_blocks[i] += 0x10;
        }
        if (binary_data[(i * 8) + 4] == '1') {
            data_blocks[i] += 0x08;
        }
        if (binary_data[(i * 8) + 5] == '1') {
            data_blocks[i] += 0x04;
        }
        if (binary_data[(i * 8) + 6] == '1') {
            data_blocks[i] += 0x02;
        }
        if (binary_data[(i * 8) + 7] == '1') {
            data_blocks[i] += 0x01;
        }
    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);







<
<
|
<
|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2405
2406
2407
2408
2409
2410
2411


2412

2413

2414
2415
2416














2417
2418
2419
2420
2421
2422
2423
        data_codewords = 10;
        ecc_codewords = 14;
    }

    /* Copy data into codewords */
    for (i = 0; i < data_codewords; i++) {
        data_blocks[i] = 0;


        

        for (j = 0; j < 8; j++) {

            if (binary_data[(i * 8) + j] == '1') {
                data_blocks[i] += 0x80 >> j;
            }














        }
    }

    /* Calculate Reed-Solomon error codewords */
    rs_init_gf(0x11d);
    rs_init_code(ecc_codewords, 0);
    rs_encode(data_codewords, data_blocks, ecc_blocks);
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
}

int micro_apply_bitmask(unsigned char *grid, int size) {
    int x, y;
    unsigned char p;
    int pattern, value[8];
    int best_val, best_pattern;
    int bit;

#ifndef _MSC_VER
    unsigned char mask[size * size];
    unsigned char eval[size * size];
#else
    unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
    unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));







<







2551
2552
2553
2554
2555
2556
2557

2558
2559
2560
2561
2562
2563
2564
}

int micro_apply_bitmask(unsigned char *grid, int size) {
    int x, y;
    unsigned char p;
    int pattern, value[8];
    int best_val, best_pattern;


#ifndef _MSC_VER
    unsigned char mask[size * size];
    unsigned char eval[size * size];
#else
    unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
    unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
            best_val = value[pattern];
        }
    }

    /* Apply mask */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {
            bit = 0;
            switch (best_pattern) {
                case 0: if (mask[(y * size) + x] & 0x01) {
                        bit = 1;
                    }
                    break;
                case 1: if (mask[(y * size) + x] & 0x02) {
                        bit = 1;
                    }
                    break;
                case 2: if (mask[(y * size) + x] & 0x04) {
                        bit = 1;
                    }
                    break;
                case 3: if (mask[(y * size) + x] & 0x08) {
                        bit = 1;
                    }
                    break;
            }
            if (bit == 1) {
                if (grid[(y * size) + x] & 0x01) {
                    grid[(y * size) + x] = 0x00;
                } else {
                    grid[(y * size) + x] = 0x01;
                }
            }
        }







<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2615
2616
2617
2618
2619
2620
2621


2622

















2623
2624
2625
2626
2627
2628
2629
            best_val = value[pattern];
        }
    }

    /* Apply mask */
    for (x = 0; x < size; x++) {
        for (y = 0; y < size; y++) {


            if (mask[(y * size) + x] & (0x01 << best_pattern)) {

















                if (grid[(y * size) + x] & 0x01) {
                    grid[(y * size) + x] = 0x00;
                } else {
                    grid[(y * size) + x] = 0x01;
                }
            }
        }
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
    int ecc_level, autoversion, version;
    int n_count, a_count, bitmask, format, format_full;
#ifdef _MSC_VER
    unsigned char* grid;
#endif

    if (length > 35) {
        strcpy(symbol->errtxt, "Input data too long");
        return ZINT_ERROR_TOO_LONG;
    }

    for (i = 0; i < 4; i++) {
        version_valid[i] = 1;
    }

    switch (symbol->input_mode) {
        case DATA_MODE:
            for (i = 0; i < length; i++) {
                jisdata[i] = (int) source[i];
            }
            break;
        default:
            /* Convert Unicode input to Shift-JIS */
            error_number = utf8toutf16(symbol, source, utfdata, &length);
            if (error_number != 0) {
                return error_number;
            }

            for (i = 0; i < length; i++) {
                if (utfdata[i] <= 0xff) {
                    jisdata[i] = utfdata[i];
                } else {
                    j = 0;
                    glyph = 0;
                    do {
                        if (sjis_lookup[j * 2] == utfdata[i]) {
                            glyph = sjis_lookup[(j * 2) + 1];
                        }
                        j++;
                    } while ((j < 6843) && (glyph == 0));
                    if (glyph == 0) {
                        strcpy(symbol->errtxt, "Invalid character in input data");
                        return ZINT_ERROR_INVALID_DATA;
                    }
                    jisdata[i] = glyph;
                }
            }
            break;
    }

    define_mode(mode, jisdata, length, 0);

    n_count = 0;
    a_count = 0;
    for (i = 0; i < length; i++) {







|







|
<
|
|
|
|
<
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660

2661
2662
2663
2664

2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689

2690
2691
2692
2693
2694
2695
2696
    int ecc_level, autoversion, version;
    int n_count, a_count, bitmask, format, format_full;
#ifdef _MSC_VER
    unsigned char* grid;
#endif

    if (length > 35) {
        strcpy(symbol->errtxt, "Input data too long (E62)");
        return ZINT_ERROR_TOO_LONG;
    }

    for (i = 0; i < 4; i++) {
        version_valid[i] = 1;
    }

    if (symbol->input_mode == DATA_MODE) {

        for (i = 0; i < length; i++) {
            jisdata[i] = (int) source[i];
        }
    } else {

        /* Convert Unicode input to Shift-JIS */
        error_number = utf8toutf16(symbol, source, utfdata, &length);
        if (error_number != 0) {
            return error_number;
        }

        for (i = 0; i < length; i++) {
            if (utfdata[i] <= 0xff) {
                jisdata[i] = utfdata[i];
            } else {
                j = 0;
                glyph = 0;
                do {
                    if (sjis_lookup[j * 2] == utfdata[i]) {
                        glyph = sjis_lookup[(j * 2) + 1];
                    }
                    j++;
                } while ((j < 6843) && (glyph == 0));
                if (glyph == 0) {
                    strcpy(symbol->errtxt, "Invalid character in input data (E63)");
                    return ZINT_ERROR_INVALID_DATA;
                }
                jisdata[i] = glyph;
            }
        }

    }

    define_mode(mode, jisdata, length, 0);

    n_count = 0;
    a_count = 0;
    for (i = 0; i < length; i++) {
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
        for (i = 0; i < length; i++) {
            mode[i] = 'N';
        }
    }

    error_number = micro_qr_intermediate(binary_stream, jisdata, mode, length, &kanji_used, &alphanum_used, &byte_used);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Input data too long");
        return error_number;
    }

    get_bitlength(binary_count, binary_stream);

    /* Eliminate possivle versions depending on type of content */
    if (byte_used) {







|







2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
        for (i = 0; i < length; i++) {
            mode[i] = 'N';
        }
    }

    error_number = micro_qr_intermediate(binary_stream, jisdata, mode, length, &kanji_used, &alphanum_used, &byte_used);
    if (error_number != 0) {
        strcpy(symbol->errtxt, "Input data too long (E64)");
        return error_number;
    }

    get_bitlength(binary_count, binary_stream);

    /* Eliminate possivle versions depending on type of content */
    if (byte_used) {
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
    if (binary_count[1] > 40) {
        version_valid[1] = 0;
    }
    if (binary_count[2] > 84) {
        version_valid[2] = 0;
    }
    if (binary_count[3] > 128) {
        strcpy(symbol->errtxt, "Input data too long");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Eliminate possible versions depending on error correction level specified */
    ecc_level = LEVEL_L;
    if ((symbol->option_1 >= 1) && (symbol->option_2 <= 4)) {
        ecc_level = symbol->option_1;
    }

    if (ecc_level == LEVEL_H) {
        strcpy(symbol->errtxt, "Error correction level H not available");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (ecc_level == LEVEL_Q) {
        version_valid[0] = 0;
        version_valid[1] = 0;
        version_valid[2] = 0;
        if (binary_count[3] > 80) {
            strcpy(symbol->errtxt, "Input data too long");
            return ZINT_ERROR_TOO_LONG;
        }
    }

    if (ecc_level == LEVEL_M) {
        version_valid[0] = 0;
        if (binary_count[1] > 32) {
            version_valid[1] = 0;
        }
        if (binary_count[2] > 68) {
            version_valid[2] = 0;
        }
        if (binary_count[3] > 112) {
            strcpy(symbol->errtxt, "Input data too long");
            return ZINT_ERROR_TOO_LONG;
        }
    }

    autoversion = 3;
    if (version_valid[2]) {
        autoversion = 2;







|










|








|













|







2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
    if (binary_count[1] > 40) {
        version_valid[1] = 0;
    }
    if (binary_count[2] > 84) {
        version_valid[2] = 0;
    }
    if (binary_count[3] > 128) {
        strcpy(symbol->errtxt, "Input data too long (E65)");
        return ZINT_ERROR_TOO_LONG;
    }

    /* Eliminate possible versions depending on error correction level specified */
    ecc_level = LEVEL_L;
    if ((symbol->option_1 >= 1) && (symbol->option_2 <= 4)) {
        ecc_level = symbol->option_1;
    }

    if (ecc_level == LEVEL_H) {
        strcpy(symbol->errtxt, "Error correction level H not available (E66)");
        return ZINT_ERROR_INVALID_OPTION;
    }

    if (ecc_level == LEVEL_Q) {
        version_valid[0] = 0;
        version_valid[1] = 0;
        version_valid[2] = 0;
        if (binary_count[3] > 80) {
            strcpy(symbol->errtxt, "Input data too long (E67)");
            return ZINT_ERROR_TOO_LONG;
        }
    }

    if (ecc_level == LEVEL_M) {
        version_valid[0] = 0;
        if (binary_count[1] > 32) {
            version_valid[1] = 0;
        }
        if (binary_count[2] > 68) {
            version_valid[2] = 0;
        }
        if (binary_count[3] > 112) {
            strcpy(symbol->errtxt, "Input data too long (E68)");
            return ZINT_ERROR_TOO_LONG;
        }
    }

    autoversion = 3;
    if (version_valid[2]) {
        autoversion = 2;
Added jni/zint/backend/raster.c.
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
/* raster.c - Handles output to raster files */

/*
    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#include <stdio.h>
#ifdef _MSC_VER
#include <fcntl.h>
#include <io.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "common.h"

#ifdef _MSC_VER
#include <malloc.h> 
#endif /* _MSC_VER */

#include "font.h" /* Font for human readable text */

#define SSET	"0123456789ABCDEF"

#ifndef NO_PNG
extern int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
#endif /* NO_PNG */
extern int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
extern int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
extern int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);

void buffer_plot(struct zint_symbol *symbol, char *pixelbuf) {
    /* Place pixelbuffer into symbol */
    int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
    int row, column, i;
    
    symbol->bitmap = (char *) malloc(symbol->bitmap_width * symbol->bitmap_height * 3);
    
    fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
    fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
    fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
    bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
    bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
    bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
    
    for (row = 0; row < symbol->bitmap_height; row++) {
        for (column = 0; column < symbol->bitmap_width; column++) {
            i = ((row * symbol->bitmap_width) + column) * 3;
            switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) {
                case '1':
                    symbol->bitmap[i] = fgred;
                    symbol->bitmap[i + 1] = fggrn;
                    symbol->bitmap[i + 2] = fgblu;
                    break;
                default:
                    symbol->bitmap[i] = bgred;
                    symbol->bitmap[i + 1] = bggrn;
                    symbol->bitmap[i + 2] = bgblu;
                    break;

            }
        }
    }
}

int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) {
    int error_number;
    int row, column;
    
    char *rotated_pixbuf;
    
    if (!(rotated_pixbuf = (char *) malloc(image_width * image_height))) {
        printf("Insufficient memory for pixel buffer (F50)");
        return ZINT_ERROR_ENCODING_PROBLEM;
    }

    switch (rotate_angle) {
        case 0:
        case 180:
            symbol->bitmap_width = image_width;
            symbol->bitmap_height = image_height;
            break;
        case 90:
        case 270:
            symbol->bitmap_width = image_height;
            symbol->bitmap_height = image_width;
            break;
    }
    
    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F51)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target (F52)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F53)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target (F54)");
        return ZINT_ERROR_INVALID_OPTION;
    }
    
    /* Rotate image before plotting */
    switch (rotate_angle) {
        case 0: /* Plot the right way up */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    rotated_pixbuf[(row * image_width) + column] =
                            pixelbuf[(image_width * row) + column];
                }
            }
            break;
        case 90: /* Plot 90 degrees clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    rotated_pixbuf[(row * image_height) + column] =
                            *(pixelbuf + (image_width * (image_height - column - 1)) + row);
                }
            }
            break;
        case 180: /* Plot upside down */
            for (row = 0; row < image_height; row++) {
                for (column = 0; column < image_width; column++) {
                    rotated_pixbuf[(row * image_width) + column] =
                            *(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1));
                }
            }
            break;
        case 270: /* Plot 90 degrees anti-clockwise */
            for (row = 0; row < image_width; row++) {
                for (column = 0; column < image_height; column++) {
                    rotated_pixbuf[(row * image_height) + column] =
                            *(pixelbuf + (image_width * column) + (image_width - row - 1));
                }
            }
            break;
    }
    
    switch (image_type) {
        case OUT_BUFFER:
            buffer_plot(symbol, rotated_pixbuf);
            error_number = 0;
            break;
        case OUT_PNG_FILE:
#ifndef NO_PNG
            error_number = png_pixel_plot(symbol, rotated_pixbuf);
#else
            return ZINT_ERROR_INVALID_OPTION;
#endif
            break;
        case OUT_PCX_FILE:
            error_number = pcx_pixel_plot(symbol, rotated_pixbuf);
            break;
        case OUT_GIF_FILE:
            error_number = gif_pixel_plot(symbol, rotated_pixbuf);
            break;
        default:
            error_number = bmp_pixel_plot(symbol, rotated_pixbuf);
            break;
    }

    free(rotated_pixbuf);
    return error_number;
}

void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) {
    /* Draw a rectangle */
    int i, j, png_ypos;

    png_ypos = image_height - ypos - ylen;
    /* This fudge is needed because EPS measures height from the bottom up but
    PNG measures y position from the top down */

    for (i = (xpos); i < (xpos + xlen); i++) {
        for (j = (png_ypos); j < (png_ypos + ylen); j++) {
            *(pixelbuf + (image_width * j) + i) = '1';
        }
    }
}

void draw_circle(char *pixelbuf, int image_width, int image_height, int x0, int y0, float radius, char fill) {
    int x, y;
    int radius_i = (int) radius;
    
    for (y = -radius_i; y <= radius_i; y++) {
        for (x = -radius_i; x <= radius_i; x++) {
            if ((x * x) + (y * y) <= (radius_i * radius_i)) {
                if ((y + y0 >= 0) && (y + y0 < image_height)
                        && (x + x0 >= 0) && (x + x0 < image_width)) {
                    *(pixelbuf + ((y + y0) * image_width) + (x + x0)) = fill;
                }
            }
        }
    }
}

void draw_bullseye(char *pixelbuf, int image_width, int image_height, int xoffset, int yoffset, int scaler) {
    /* Central bullseye in Maxicode symbols */
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(4.571 * scaler) + 1, '1');
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(3.779 * scaler) + 1, '0');
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(2.988 * scaler) + 1, '1');
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(2.196 * scaler) + 1, '0');
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(1.394 * scaler) + 1, '1');
    draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(0.602 * scaler) + 1, '0');

}

void draw_hexagon(char *pixelbuf, int image_width, char *scaled_hexagon, int hexagon_size, int xposn, int yposn) {
    /* Put a hexagon into the pixel buffer */
    int i, j;

    for (i = 0; i < hexagon_size; i++) {
        for (j = 0; j < hexagon_size; j++) {
            if (scaled_hexagon[(i * hexagon_size) + j] == '1') {
                *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = '1';
            }
        }
    }
}

void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int textflags, int image_width, int image_height) {
    /* Put a letter into a position */
    int skip, x, y, glyph_no, max_x, max_y;

    skip = 0;

    if (letter < 33) {
        skip = 1;
    }

    if ((letter > 127) && (letter < 161)) {
        skip = 1;
    }

    if (xposn < 0 || yposn < 0) {
        skip = 1;
    }

    if (skip == 0) {
        if (letter > 128) {
            glyph_no = letter - 66;
        } else {
            glyph_no = letter - 33;
        }


        switch (textflags) {
            case 1: // small font 5x9
                max_x = 5;
                max_y = 9;

                if (xposn + max_x >= image_width) {
                    max_x = image_width - xposn - 1;
                }

                if (yposn + max_y >= image_height) {
                    max_y = image_height - yposn - 1;
                }

                for (y = 0; y < max_y; y++) {
                    for (x = 0; x < max_x; x++) {
                        if (small_font[(glyph_no * 9) + y] & (0x10 >> x)) {
                            *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1';
                        }
                    }
                }
                break;

            case 2: // bold font -> twice the regular font
            {
                char * linePtr;
                max_x = 7;
                max_y = 14;

                if (xposn + max_x + 1 >= image_width) {
                    max_x = image_width - xposn - 2;
                }

                if (yposn + max_y >= image_height) {
                    max_y = image_height - yposn - 1;
                }

                linePtr = pixelbuf + (yposn * image_width) + xposn + 1;
                for (y = 0; y < max_y; y++) {
                    char * pixelPtr = linePtr;
                    int extra_dot = 0;
                    for (x = 0; x < 7; x++) {
                        if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) {
                            *pixelPtr = '1';
                            extra_dot = 1;
                        } else {
                            if (extra_dot) {
                                *pixelPtr = '1';
                            }

                            extra_dot = 0;
                        }

                        ++pixelPtr;
                    }

                    if (extra_dot) {
                        *pixelPtr = '1';
                    }

                    linePtr += image_width;
                }
            }
                break;

            default: // regular font 7x15
                max_x = 7;
                max_y = 14;

                if (xposn + max_x >= image_width) {
                    max_x = image_width - xposn - 1;
                }

                if (yposn + max_y >= image_height) {
                    max_y = image_height - yposn - 1;
                }

                for (y = 0; y < max_y; y++) {
                    for (x = 0; x < 7; x++) {
                        if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) {
                            *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1';
                        }
                    }
                }
                break;
        }
    }
}

/* Plot a string into the pixel buffer */
void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int textflags, int image_width, int image_height) {
    int i, string_length, string_left_hand, letter_width = 7;

    switch (textflags) {
        case 1: // small font 5x9
            letter_width = 5;
            break;

        case 2: // bold font -> width of the regular font + 1 extra dot + 1 extra space
            letter_width = 9;
            break;

        default: // regular font 7x15
            letter_width = 7;
            break;
    }

    string_length = strlen(input_string);
    string_left_hand = xposn - ((letter_width * string_length) / 2);

    for (i = 0; i < string_length; i++) {
        draw_letter(pixbuf, input_string[i], string_left_hand + (i * letter_width), yposn, textflags, image_width, image_height);
    }

}

void plot_hexline(char *scaled_hexagon, int hexagon_size, float start_x, float start_y, float end_x, float end_y) {
    /* Draw a straight line from start to end */
    int i;
    float inc_x, inc_y;
    float this_x, this_y;
    
    inc_x = (end_x - start_x) / hexagon_size;
    inc_y = (end_y - start_y) / hexagon_size;
    
    for (i = 0; i < hexagon_size; i++) {
        this_x = start_x + ((float)i * inc_x);
        this_y = start_y + ((float)i * inc_y);
        if (((this_x >= 0) && (this_x < hexagon_size)) && ((this_y >= 0) && (this_y < hexagon_size))) {
                scaled_hexagon[(hexagon_size * (int)this_y) + (int)this_x] = '1';
        }
    }
}

void plot_hexagon(char *scaled_hexagon, int hexagon_size) {
    /* Create a hexagon shape and fill it */
    int line, i;
    char ink;
    
    float x_offset[6];
    float y_offset[6];
    float start_x, start_y;
    float end_x, end_y;
    
    x_offset[0] = 0.0;
    x_offset[1] = 0.86;
    x_offset[2] = 0.86;
    x_offset[3] = 0.0;
    x_offset[4] = -0.86;
    x_offset[5] = -0.86;
    
    y_offset[0] = 1.0;
    y_offset[1] = 0.5;
    y_offset[2] = -0.5;
    y_offset[3] = -1.0;
    y_offset[4] = -0.5;
    y_offset[5] = 0.5;
    
    /* Plot hexagon outline */
    for (line = 0; line < 5; line++) {
        start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]);
        start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]);
        end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line + 1]);
        end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line + 1]);
        plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y);
    }
    start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]);
    start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]);
    end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[0]);
    end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[0]);
    plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y);
    
    /* Fill hexagon */
    for (line = 0; line < hexagon_size; line++) {
        ink = '0';
        for (i = 0; i < hexagon_size; i++) {
            if (scaled_hexagon[(hexagon_size * line) + i] == '1') {
                if (i < (hexagon_size / 2)) {
                    ink = '1';
                } else {
                    ink = '0';
                }
            }
            
            if (ink == '1') {
                scaled_hexagon[(hexagon_size * line) + i] = ink;
            }
        }
    }
}

int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_type) {
    /* Plot a MaxiCode symbol with hexagons and bullseye */
    int i, row, column, xposn, yposn;
    int image_height, image_width;
    char *pixelbuf;
    int error_number;
    int xoffset, yoffset;
    float scaler = symbol->scale;
    char *scaled_hexagon;
    int hexagon_size;

    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;
    image_width = (300 + (2 * xoffset * 2)) * scaler;
    image_height = (300 + (2 * yoffset * 2)) * scaler;

    if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
        printf("Insufficient memory for pixel buffer (F55)");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (image_width * image_height); i++) {
            *(pixelbuf + i) = '0';
        }
    }
    
    hexagon_size = (int)scaler * 10;
    
    if (!(scaled_hexagon = (char *) malloc(hexagon_size * hexagon_size))) {
        printf("Insufficient memory for pixel buffer (F56)");
        free(scaled_hexagon);
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (hexagon_size * hexagon_size); i++) {
            *(scaled_hexagon + i) = '0';
        }
    }
    
    plot_hexagon(scaled_hexagon, hexagon_size);

    draw_bullseye(pixelbuf, image_width, image_height, (2 * xoffset), (2 * yoffset), scaler * 10);

    for (row = 0; row < symbol->rows; row++) {
        yposn = row * 9;
        for (column = 0; column < symbol->width; column++) {
            xposn = column * 10;
            if (module_is_set(symbol, row, column)) {
                if (row & 1) {
                    /* Odd (reduced) row */
                    xposn += 5;
                    draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler);
                } else {
                    /* Even (full) row */
                    draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler);
                }
            }
        }
    }

    if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
        /* boundary bars */
        draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height);
        draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height);
    }

    if (symbol->output_options & BARCODE_BOX) {
        /* side bars */
        draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height);
        draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height);
    }

    error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
    free(scaled_hexagon);
    free(pixelbuf);
    return error_number;
}

/* Convert UTF-8 to Latin1 Codepage for the interpretation line */
void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
    int j, i, input_length;

    input_length = ustrlen(source);

    j = 0;
    i = 0;
    while (i < input_length) {
        switch (source[i]) {
            case 0xC2:
                /* UTF-8 C2xxh */
                /* Character range: C280h (latin: 80h) to C2BFh (latin: BFh) */
                i++;
                preprocessed[j] = source[i];
                j++;
                break;
            case 0xC3:
                /* UTF-8 C3xx */
                /* Character range: C380h (latin: C0h) to C3BFh (latin: FFh) */
                i++;
                preprocessed[j] = source[i] + 64;
                j++;
                break;
            default:
                /* Process ASCII (< 80h), all other unicode points are ignored */
                if (source[i] < 128) {
                    preprocessed[j] = source[i];
                    j++;
                }
                break;
        }
        i++;
    }
    preprocessed[j] = '\0';

    return;
}

int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) {
    float scaler = 2 * symbol->scale;
    char *scaled_pixelbuf;
    int r, i;
    int scale_width, scale_height;
    int error_number = 0;
    int xoffset, yoffset, image_width, image_height;

    symbol->height = symbol->rows; // This is true because only 2d matrix symbols are processed here

    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;
    image_width = symbol->width + xoffset + xoffset;
    image_height = symbol->height + yoffset + yoffset;

    if (scaler < 2.0) {
        scaler = 2.0;
    }
    scale_width = (image_width * scaler) + 1;
    scale_height = (image_height * scaler) + 1;

    /* Apply scale options by creating another pixel buffer */
    if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
        printf("Insufficient memory for pixel buffer (F57)");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (scale_width * scale_height); i++) {
            *(scaled_pixelbuf + i) = '0';
        }
    }

    /* Plot the body of the symbol to the pixel buffer */
    for (r = 0; r < symbol->rows; r++) {
        for (i = 0; i < symbol->width; i++) {
            if (module_is_set(symbol, r, i)) {
                draw_circle(scaled_pixelbuf, scale_width, scale_height,
                        (int) ((i + xoffset) * scaler) + (scaler / 2.0),
                        (int) ((r + yoffset) * scaler) + (scaler / 2.0),
                        (symbol->dot_size / 2.0) * scaler,
                        '1');
            }
        }
    }

    error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
    free(scaled_pixelbuf);

    return error_number;
}

int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_type) {
    int textdone, main_width, comp_offset, large_bar_count;
    char textpart[10], addon[6];
    float addon_text_posn, preset_height, large_bar_height;
    int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height;
    char *pixelbuf;
    int addon_latch = 0, textflags = 0;
    int this_row, block_width, plot_height, plot_yposn, textpos;
    float row_height, row_posn;
    int error_number;
    int default_text_posn;
    int next_yposn;
    float scaler = symbol->scale;
    char *scaled_pixelbuf;
    int horiz, vert;
    int scale_width, scale_height;
#ifndef _MSC_VER
    unsigned char local_text[ustrlen(symbol->text) + 1];
#else
    unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1);
#endif

    if (symbol->show_hrt != 0) {
        /* Copy text from symbol */
        to_latin1(symbol->text, local_text);
    } else {
        /* No text needed */
        switch (symbol->symbology) {
            case BARCODE_EANX:
            case BARCODE_EANX_CC:
            case BARCODE_ISBNX:
            case BARCODE_UPCA:
            case BARCODE_UPCE:
            case BARCODE_UPCA_CC:
            case BARCODE_UPCE_CC:
                /* For these symbols use dummy text to ensure formatting is done
                 * properly even if no text is required */
                for (i = 0; i < ustrlen(symbol->text); i++) {
                    if (symbol->text[i] == '+') {
                        local_text[i] = '+';
                    } else {
                        local_text[i] = ' ';
                    }
                    local_text[ustrlen(symbol->text)] = '\0';
                }
                break;
            default:
                /* For everything else, just remove the text */
                local_text[0] = '\0';
                break;
        }
    }

    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;
    row_height = 0;
    if (symbol->output_options & SMALL_TEXT) {
        textflags = 1;
    } else if (symbol->output_options & BOLD_TEXT) {
        textflags = 2;
    }

    if (symbol->height == 0) {
        symbol->height = 50;
    }

    large_bar_count = 0;
    preset_height = 0.0;
    for (i = 0; i < symbol->rows; i++) {
        preset_height += symbol->row_height[i];
        if (symbol->row_height[i] == 0) {
            large_bar_count++;
        }
    }

    if (large_bar_count == 0) {
        symbol->height = preset_height;
        large_bar_height = 10;
    } else {
        large_bar_height = (symbol->height - preset_height) / large_bar_count;
    }

    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(local_text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;
                break;
            default:
                main_width = 68 + comp_offset;
        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        if (symbol->whitespace_width == 0) {
            symbol->whitespace_width = 10;
            main_width = 96 + comp_offset;
        }
    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        if (symbol->whitespace_width == 0) {
            symbol->whitespace_width = 10;
            main_width = 51 + comp_offset;
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(local_text); i++) {
            if (latch == 1) {
                addon[r] = local_text[i];
                r++;
            }
            if (symbol->text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';

    if (ustrlen(local_text) != 0) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }

    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;
    image_width = 2 * (symbol->width + xoffset + xoffset);
    image_height = 2 * (symbol->height + textoffset + yoffset + yoffset);

    if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
        printf("Insufficient memory for pixel buffer (F58)");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (image_width * image_height); i++) {
            *(pixelbuf + i) = '0';
        }
    }

    if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
        default_text_posn = image_height - 17;
    } else {
        default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width;
    }

    row_posn = textoffset + yoffset;
    next_yposn = textoffset + yoffset;
    row_height = 0;

    /* Plot the body of the symbol to the pixel buffer */
    for (r = 0; r < symbol->rows; r++) {
        this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
        row_posn += row_height;
        plot_yposn = next_yposn;
        if (symbol->row_height[this_row] == 0) {
            row_height = large_bar_height;
        } else {
            row_height = symbol->row_height[this_row];
        }
        next_yposn = (int) (row_posn + row_height);
        plot_height = next_yposn - plot_yposn;

        i = 0;
        if (module_is_set(symbol, this_row, 0)) {
            latch = 1;
        } else {
            latch = 0;
        }

        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
            if ((addon_latch == 0) && (r == 0) && (i > main_width)) {
                plot_height = (int) (row_height - 5.0);
                plot_yposn = (int) (row_posn - 5.0);
                addon_text_posn = row_posn + row_height - 8.0;
                addon_latch = 1;
            }
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;

        } while (i < symbol->width);
    }

    xoffset += comp_offset;

    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) {
        /* guard bar extensions and text formatting for EAN8 and EAN13 */
        switch (ustrlen(local_text)) {
            case 8: /* EAN-8 */
            case 11:
            case 14:
                draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i];
                }
                textpart[4] = '\0';
                textpos = 2 * (17 + xoffset);

                draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i + 4];
                }
                textpart[4] = '\0';
                textpos = 2 * (50 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = 2 * (xoffset + 86);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                        break;
                    case 5:
                        textpos = 2 * (xoffset + 100);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                        break;
                }

                break;
            case 13: /* EAN 13 */
            case 16:
            case 19:
                draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);

                textpart[0] = local_text[0];
                textpart[1] = '\0';
                textpos = 2 * (-7 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 1];
                }
                textpart[6] = '\0';
                textpos = 2 * (24 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 7];
                }
                textpart[6] = '\0';
                textpos = 2 * (71 + xoffset);
                draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = 2 * (xoffset + 114);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                        break;
                    case 5:
                        textpos = 2 * (xoffset + 128);
                        draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                        break;
                }
                break;

        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        /* guard bar extensions and text formatting for UPCA */
        latch = 1;

        i = 0 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 11 + comp_offset);
        draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        latch = 1;
        i = 85 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 96 + comp_offset);
        textpart[0] = local_text[0];
        textpart[1] = '\0';
        textpos = 2 * (-5 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[5] = '\0';
        textpos = 2 * (27 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 6];
        }
        textpart[6] = '\0';
        textpos = 2 * (68 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        textpart[0] = local_text[11];
        textpart[1] = '\0';
        textpos = 2 * (100 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = 2 * (xoffset + 116);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                break;
            case 5:
                textpos = 2 * (xoffset + 130);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                break;
        }

    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        /* guard bar extensions and text formatting for UPCE */
        draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);
        draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height);

        textpart[0] = local_text[0];
        textpart[1] = '\0';
        textpos = 2 * (-5 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        for (i = 0; i < 6; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[6] = '\0';
        textpos = 2 * (24 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        textpart[0] = local_text[7];
        textpart[1] = '\0';
        textpos = 2 * (55 + xoffset);
        draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = 2 * (xoffset + 70);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                break;
            case 5:
                textpos = 2 * (xoffset + 84);
                draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
                break;
        }

    }

    xoffset -= comp_offset;

    /* Put boundary bars or box around symbol */
    if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
        /* boundary bars */
        if (symbol->symbology != BARCODE_CODABLOCKF) {
            draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height);
            draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height);
        } else {
            draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height);
            draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height);
        }
        if ((symbol->output_options & BARCODE_BIND) != 0) {
            if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                /* row binding */
                if (symbol->symbology != BARCODE_CODABLOCKF) {
                    for (r = 1; r < symbol->rows; r++) {
                        draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height);
                    }
                } else {
                    for (r = 1; r < symbol->rows; r++) {
                        draw_bar(pixelbuf, (xoffset + 11) * 2 , (symbol->width - 25) * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height);
                    }
                }
            }
        }
    }

    if (symbol->output_options & BARCODE_BOX) {
        /* side bars */
        draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height);
        draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height);
    }

    /* Put the human readable text at the bottom */
    if ((textdone == 0) && (ustrlen(local_text) != 0)) {
        textpos = (image_width / 2);
        draw_string(pixelbuf, (char*) local_text, textpos, default_text_posn, textflags, image_width, image_height);
    }


    if (scaler == 0) {
        scaler = 0.5;
    }
    scale_width = image_width * scaler;
    scale_height = image_height * scaler;

    /* Apply scale options by creating another pixel buffer */
    if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
        free(pixelbuf);
        printf("Insufficient memory for pixel buffer (F59)");
        return ZINT_ERROR_ENCODING_PROBLEM;
    } else {
        for (i = 0; i < (scale_width * scale_height); i++) {
            *(scaled_pixelbuf + i) = '0';
        }
    }

    for (vert = 0; vert < scale_height; vert++) {
        for (horiz = 0; horiz < scale_width; horiz++) {
            *(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler));
        }
    }

    error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
    free(scaled_pixelbuf);
    free(pixelbuf);
    return error_number;
}

int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) {
    int error;

#ifdef NO_PNG
    if (file_type == OUT_PNG_FILE) {
        return ZINT_ERROR_INVALID_OPTION;
    }
#endif /* NO_PNG */    

    if (symbol->output_options & BARCODE_DOTTY_MODE) {
        error = plot_raster_dotty(symbol, rotate_angle, file_type);
    } else {
        if (symbol->symbology == BARCODE_MAXICODE) {
            error = plot_raster_maxicode(symbol, rotate_angle, file_type);
        } else {
            error = plot_raster_default(symbol, rotate_angle, file_type);
        }
    }

    return error;
}
Changes to jni/zint/backend/render.c.
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
        symbol->height = (int) ((height / scaler) - ((2 * yoffset) + text_offset + text_height));

        render->width = width;
        render->height = height;
    }
    large_bar_height = (symbol->height - preset_height) / large_bar_count;

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler;
    } else {
        default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler;
    }

    x_dimension = render->width / total_area_width_x;
    x_dimension /= GL_CONST;







|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
        symbol->height = (int) ((height / scaler) - ((2 * yoffset) + text_offset + text_height));

        render->width = width;
        render->height = height;
    }
    large_bar_height = (symbol->height - preset_height) / large_bar_count;

    if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
        default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler;
    } else {
        default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler;
    }

    x_dimension = render->width / total_area_width_x;
    x_dimension /= GL_CONST;
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
                    /* row binding */
                    for (r = 1; r < symbol->rows; r++) {
                        line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler);
                        render_plot_add_line(symbol, line, &last_line);
                    }
                }
            }
            if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
                line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                render_plot_add_line(symbol, line, &last_line);
                line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                render_plot_add_line(symbol, line, &last_line);
            }
            if ((symbol->output_options & BARCODE_BOX) != 0) {
                /* side bars */
                line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                render_plot_add_line(symbol, line, &last_line);
                line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                render_plot_add_line(symbol, line, &last_line);
            }
            break;







|





|







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
                    /* row binding */
                    for (r = 1; r < symbol->rows; r++) {
                        line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler);
                        render_plot_add_line(symbol, line, &last_line);
                    }
                }
            }
            if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
                line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                render_plot_add_line(symbol, line, &last_line);
                line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                render_plot_add_line(symbol, line, &last_line);
            }
            if (symbol->output_options & BARCODE_BOX) {
                /* side bars */
                line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                render_plot_add_line(symbol, line, &last_line);
                line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                render_plot_add_line(symbol, line, &last_line);
            }
            break;
Changes to jni/zint/backend/rss.c.
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer;
    char latch, hrt[15], temp[32];
    int check_digit, count, separator_row;

    separator_row = 0;

    if (src_len > 13) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* make some room for a separator row for composite symbols */
    switch (symbol->symbology) {
        case BARCODE_RSS14_CC:
        case BARCODE_RSS14STACK_CC:







|




|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer;
    char latch, hrt[15], temp[32];
    int check_digit, count, separator_row;

    separator_row = 0;

    if (src_len > 13) {
        strcpy(symbol->errtxt, "Input too long (C80)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C81)");
        return error_number;
    }

    /* make some room for a separator row for composite symbols */
    switch (symbol->symbology) {
        case BARCODE_RSS14_CC:
        case BARCODE_RSS14STACK_CC:
510
511
512
513
514
515
516


517
518
519
520
521
522
523
        check_digit = 10 - (count % 10);
        if (check_digit == 10) {
            check_digit = 0;
        }
        hrt[13] = itoc(check_digit);

        strcat((char*) symbol->text, hrt);


    }

    if ((symbol->symbology == BARCODE_RSS14STACK) || (symbol->symbology == BARCODE_RSS14STACK_CC)) {
        /* top row */
        writer = 0;
        latch = '0';
        for (i = 0; i < 23; i++) {







>
>







510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
        check_digit = 10 - (count % 10);
        if (check_digit == 10) {
            check_digit = 0;
        }
        hrt[13] = itoc(check_digit);

        strcat((char*) symbol->text, hrt);
        
        set_minimum_height(symbol, 14); // Minimum height is 14X for truncated symbol
    }

    if ((symbol->symbology == BARCODE_RSS14STACK) || (symbol->symbology == BARCODE_RSS14STACK_CC)) {
        /* top row */
        writer = 0;
        latch = '0';
        for (i = 0; i < 23; i++) {
712
713
714
715
716
717
718


719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
                } else {
                    unset_module(symbol, separator_row, i);
                    latch = '1';
                }
            }
        }
        symbol->rows = symbol->rows + 1;


    }


    return error_number;
}

/* GS1 DataBar Limited */
int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    int error_number = 0, i, mask;
    short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112];
    int left_group, right_group, left_odd, left_even, right_odd, right_even;
    int left_character, right_character, left_widths[14], right_widths[14];
    int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count;
    char latch, hrt[15], temp[32];
    int separator_row;

    separator_row = 0;

    if (src_len > 13) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }
    if (src_len == 13) {
        if ((source[0] != '0') && (source[0] != '1')) {
            strcpy(symbol->errtxt, "Input out of range");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* make some room for a separator row for composite symbols */
    if (symbol->symbology == BARCODE_RSS_LTD_CC) {
        separator_row = symbol->rows;







>
>



















|




|




|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
                } else {
                    unset_module(symbol, separator_row, i);
                    latch = '1';
                }
            }
        }
        symbol->rows = symbol->rows + 1;
        
        set_minimum_height(symbol, 33);
    }


    return error_number;
}

/* GS1 DataBar Limited */
int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    int error_number = 0, i, mask;
    short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112];
    int left_group, right_group, left_odd, left_even, right_odd, right_even;
    int left_character, right_character, left_widths[14], right_widths[14];
    int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count;
    char latch, hrt[15], temp[32];
    int separator_row;

    separator_row = 0;

    if (src_len > 13) {
        strcpy(symbol->errtxt, "Input too long (C82)");
        return ZINT_ERROR_TOO_LONG;
    }
    error_number = is_sane(NEON, source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C83)");
        return error_number;
    }
    if (src_len == 13) {
        if ((source[0] != '0') && (source[0] != '1')) {
            strcpy(symbol->errtxt, "Input out of range (C84)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    /* make some room for a separator row for composite symbols */
    if (symbol->symbology == BARCODE_RSS_LTD_CC) {
        separator_row = symbol->rows;
1038
1039
1040
1041
1042
1043
1044


1045
1046
1047
1048
1049
1050
1051
        check_digit = 0;
    }

    hrt[13] = itoc(check_digit);
    hrt[14] = '\0';

    strcat((char*) symbol->text, hrt);



    return error_number;
}

/* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3
 * of ISO/IEC 24724:2006 */
int general_rules(char field[], char type[]) {







>
>







1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
        check_digit = 0;
    }

    hrt[13] = itoc(check_digit);
    hrt[14] = '\0';

    strcat((char*) symbol->text, hrt);
    
    set_minimum_height(symbol, 10);

    return error_number;
}

/* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3
 * of ISO/IEC 24724:2006 */
int general_rules(char field[], char type[]) {
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
            block[0][block_count] = 1;
            block[1][block_count] = type[i];
        }
    }

    block_count++;

    for (i = 0; i < block_count; i++) {
    }

    for (i = 0; i < block_count; i++) {
        current = block[1][i];
        next = (block[1][i + 1] & 0xFF);

        if ((current == ISOIEC) && (i != (block_count - 1))) {
            if ((next == ANY_ENC) && (block[0][i + 1] >= 4)) {
                block[1][i + 1] = NUMERIC;







<
<
<







1075
1076
1077
1078
1079
1080
1081



1082
1083
1084
1085
1086
1087
1088
            block[0][block_count] = 1;
            block[1][block_count] = type[i];
        }
    }

    block_count++;




    for (i = 0; i < block_count; i++) {
        current = block[1][i];
        next = (block[1][i + 1] & 0xFF);

        if ((current == ISOIEC) && (i != (block_count - 1))) {
            if ((next == ANY_ENC) && (block[0][i + 1] >= 4)) {
                block[1][i + 1] = NUMERIC;
1163
1164
1165
1166
1167
1168
1169

1170
1171
1172
1173
1174
1175
1176
        return 0;
    }
}

/* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */
int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) {
    int encoding_method, i, mask, j, read_posn, latch, debug = 0, last_mode = ISOIEC;

#ifndef _MSC_VER
    char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1];
#else
    char* general_field = (char*) _alloca(strlen(source) + 1);
    char* general_field_type = (char*) _alloca(strlen(source) + 1);
#endif
    int remainder, d1, d2, value;







>







1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
        return 0;
    }
}

/* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */
int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) {
    int encoding_method, i, mask, j, read_posn, latch, debug = 0, last_mode = ISOIEC;
    int symbol_characters, characters_per_row;
#ifndef _MSC_VER
    char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1];
#else
    char* general_field = (char*) _alloca(strlen(source) + 1);
    char* general_field_type = (char*) _alloca(strlen(source) + 1);
#endif
    int remainder, d1, d2, value;
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389

    /* Verify that the data to be placed in the compressed data field is all
    numeric data before carrying out compression */
    for (i = 0; i < read_posn; i++) {
        if ((source[i] < '0') || (source[i] > '9')) {
            if ((source[i] != '[') && (source[i] != ']')) {
                /* Something is wrong */
                strcpy(symbol->errtxt, "Invalid characters in input data");
                return ZINT_ERROR_INVALID_DATA;
            }
        }
    }

    /* Now encode the compressed data field */








|







1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393

    /* Verify that the data to be placed in the compressed data field is all
    numeric data before carrying out compression */
    for (i = 0; i < read_posn; i++) {
        if ((source[i] < '0') || (source[i] > '9')) {
            if ((source[i] != '[') && (source[i] != ']')) {
                /* Something is wrong */
                strcpy(symbol->errtxt, "Invalid characters in input data (C85)");
                return ZINT_ERROR_INVALID_DATA;
            }
        }
    }

    /* Now encode the compressed data field */

1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
    }

    general_field_type[strlen(general_field)] = '\0';
    if (debug) printf("General field type: %s\n", general_field_type);

    if (latch == 1) {
        /* Invalid characters in input data */
        strcpy(symbol->errtxt, "Invalid characters in input data");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < strlen(general_field); i++) {
        if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) {
            general_field_type[i + 1] = ISOIEC;
        }







|







1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
    }

    general_field_type[strlen(general_field)] = '\0';
    if (debug) printf("General field type: %s\n", general_field_type);

    if (latch == 1) {
        /* Invalid characters in input data */
        strcpy(symbol->errtxt, "Invalid characters in input data (C86)");
        return ZINT_ERROR_INVALID_DATA;
    }

    for (i = 0; i < strlen(general_field); i++) {
        if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) {
            general_field_type[i + 1] = ISOIEC;
        }
1910
1911
1912
1913
1914
1915
1916
1917
1918


1919


1920
















1921
1922
1923
1924
1925
1926
1927
    if (debug) printf("Resultant binary = %s\n", binary_string);
    if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));

    remainder = 12 - (strlen(binary_string) % 12);
    if (remainder == 12) {
        remainder = 0;
    }
    if (strlen(binary_string) < 36) {
        remainder = 36 - strlen(binary_string);


    }



















    if (latch == 1) {
        /* There is still one more numeric digit to encode */
        if (debug) printf("Adding extra (odd) numeric digit\n");

        if (last_mode == NUMERIC) {
            if ((remainder >= 4) && (remainder <= 6)) {
                value = ctoi(general_field[i]);







|
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
    if (debug) printf("Resultant binary = %s\n", binary_string);
    if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));

    remainder = 12 - (strlen(binary_string) % 12);
    if (remainder == 12) {
        remainder = 0;
    }
    symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1;
    
    if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) {
        characters_per_row = symbol->option_2 * 2;
        
        if ((characters_per_row < 2) || (characters_per_row > 20)) {
            characters_per_row = 4;
        }
        
        if ((symbol_characters % characters_per_row) == 1) {
            symbol_characters++;
        }
        
        if (symbol_characters < 4) {
            symbol_characters = 4;
        }
    }
    
    if (symbol_characters < 3) {
        symbol_characters = 3;
    }
    
    remainder = (12 * (symbol_characters - 1)) - strlen(binary_string);
    
    if (latch == 1) {
        /* There is still one more numeric digit to encode */
        if (debug) printf("Adding extra (odd) numeric digit\n");

        if (last_mode == NUMERIC) {
            if ((remainder >= 4) && (remainder <= 6)) {
                value = ctoi(general_field[i]);
1954
1955
1956
1957
1958
1959
1960
1961
1962


1963



















1964
1965
1966
1967
1968
1969
1970
            }
        }

        remainder = 12 - (strlen(binary_string) % 12);
        if (remainder == 12) {
            remainder = 0;
        }
        if (strlen(binary_string) < 36) {
            remainder = 36 - strlen(binary_string);


        }



















        if (debug) printf("Resultant binary = %s\n", binary_string);
        if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));
    }

    if (strlen(binary_string) > 252) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;







|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
            }
        }

        remainder = 12 - (strlen(binary_string) % 12);
        if (remainder == 12) {
            remainder = 0;
        }
        symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1;

        if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) {
            characters_per_row = symbol->option_2 * 2;

            if ((characters_per_row < 2) || (characters_per_row > 20)) {
                characters_per_row = 4;
            }

            if ((symbol_characters % characters_per_row) == 1) {
                symbol_characters++;
            }

            if (symbol_characters < 4) {
                symbol_characters = 4;
            }
        }

        if (symbol_characters < 3) {
            symbol_characters = 3;
        }

        remainder = (12 * (symbol_characters - 1)) - strlen(binary_string);
        
        if (debug) printf("Resultant binary = %s\n", binary_string);
        if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));
    }

    if (strlen(binary_string) > 252) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
1980
1981
1982
1983
1984
1985
1986
1987
1988

1989
1990
1991
1992
1993
1994
1995
1996
1997
    }
    for (; i > 0; i -= 5) {
        strcat(padstring, "00100");
    }

    padstring[remainder] = '\0';
    strcat(binary_string, padstring);

    /* Patch variable length symbol bit field */

    d1 = ((strlen(binary_string) / 12) + 1) & 1;
    if (strlen(binary_string) <= 156) {
        d2 = 0;
    } else {
        d2 = 1;
    }

    if (encoding_method == 1) {
        binary_string[2] = d1 ? '1' : '0';







|

>
|
|







2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
    }
    for (; i > 0; i -= 5) {
        strcat(padstring, "00100");
    }

    padstring[remainder] = '\0';
    strcat(binary_string, padstring);
    
    /* Patch variable length symbol bit field */
    d1 = symbol_characters & 1;

    if (symbol_characters <= 14) {
        d2 = 0;
    } else {
        d2 = 1;
    }

    if (encoding_method == 1) {
        binary_string[2] = d1 ? '1' : '0';
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
    if (debug) printf("Resultant binary = %s\n", binary_string);
    if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));
    return 0;
}

/* GS1 DataBar Expanded */
int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    int i, j, k, l, p, data_chars, vs[21], group[21], v_odd[21], v_even[21];
    char substring[21][14], latch;
    int char_widths[21][8], checksum, check_widths[8], c_group;
    int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer;
    int row, elements_in_sub, special_case_row, left_to_right;
    int codeblocks, sub_elements[235], stack_rows, current_row, current_block;
    int separator_row;
#ifndef _MSC_VER







|







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
    if (debug) printf("Resultant binary = %s\n", binary_string);
    if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));
    return 0;
}

/* GS1 DataBar Expanded */
int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    int i, j, k, p, data_chars, vs[21], group[21], v_odd[21], v_even[21];
    char substring[21][14], latch;
    int char_widths[21][8], checksum, check_widths[8], c_group;
    int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer;
    int row, elements_in_sub, special_case_row, left_to_right;
    int codeblocks, sub_elements[235], stack_rows, current_row, current_block;
    int separator_row;
#ifndef _MSC_VER
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170

    /* Initialise element array */
    pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) & 1)) * 5) + ((data_chars + 1) * 8) + 4;
    for (i = 0; i < pattern_width; i++) {
        elements[i] = 0;
    }

    elements[0] = 1;
    elements[1] = 1;
    elements[pattern_width - 2] = 1;
    elements[pattern_width - 1] = 1;

    /* Put finder patterns in element array */
    for (i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) {
        k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11) + i;
        for (j = 0; j < 5; j++) {
            elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j];
        }
    }







<
<
<
<
<







2198
2199
2200
2201
2202
2203
2204





2205
2206
2207
2208
2209
2210
2211

    /* Initialise element array */
    pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) & 1)) * 5) + ((data_chars + 1) * 8) + 4;
    for (i = 0; i < pattern_width; i++) {
        elements[i] = 0;
    }






    /* Put finder patterns in element array */
    for (i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) {
        k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11) + i;
        for (j = 0; j < 5; j++) {
            elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j];
        }
    }
2186
2187
2188
2189
2190
2191
2192







2193
2194
2195
2196
2197
2198
2199
        for (j = 0; j < 8; j++) {
            elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j];
        }
    }

    if ((symbol->symbology == BARCODE_RSS_EXP) || (symbol->symbology == BARCODE_RSS_EXP_CC)) {
        /* Copy elements into symbol */







        writer = 0;
        latch = '0';
        for (i = 0; i < pattern_width; i++) {
            for (j = 0; j < elements[i]; j++) {
                if (latch == '1') {
                    set_module(symbol, symbol->rows, writer);
                } else {







>
>
>
>
>
>
>







2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
        for (j = 0; j < 8; j++) {
            elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j];
        }
    }

    if ((symbol->symbology == BARCODE_RSS_EXP) || (symbol->symbology == BARCODE_RSS_EXP_CC)) {
        /* Copy elements into symbol */
        
        elements[0] = 1; // left guard
        elements[1] = 1;
        
        elements[pattern_width - 2] = 1; // right guard
        elements[pattern_width - 1] = 1;
        
        writer = 0;
        latch = '0';
        for (i = 0; i < pattern_width; i++) {
            for (j = 0; j < elements[i]; j++) {
                if (latch == '1') {
                    set_module(symbol, symbol->rows, writer);
                } else {
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
        /* RSS Expanded Stacked */

        /* Bug corrected: Character missing for message
         * [01]90614141999996[10]1234222222222221
         * Patch by Daniel Frede
         */
        codeblocks = (data_chars + 1) / 2 + ((data_chars + 1) % 2);


        if ((symbol->option_2 < 1) || (symbol->option_2 > 10)) {
            symbol->option_2 = 2;
        }
        if ((symbol->option_1 == 2) && (symbol->option_2 == 1)) {
            /* "There shall be a minimum of four symbol characters in the
            first row of an RSS Expanded Stacked symbol when it is the linear







>







2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
        /* RSS Expanded Stacked */

        /* Bug corrected: Character missing for message
         * [01]90614141999996[10]1234222222222221
         * Patch by Daniel Frede
         */
        codeblocks = (data_chars + 1) / 2 + ((data_chars + 1) % 2);


        if ((symbol->option_2 < 1) || (symbol->option_2 > 10)) {
            symbol->option_2 = 2;
        }
        if ((symbol->option_1 == 2) && (symbol->option_2 == 1)) {
            /* "There shall be a minimum of four symbol characters in the
            first row of an RSS Expanded Stacked symbol when it is the linear
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296

2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
        for (current_row = 1; current_row <= stack_rows; current_row++) {
            for (i = 0; i < 235; i++) {
                sub_elements[i] = 0;
            }
            special_case_row = 0;

            /* Row Start */
            sub_elements[0] = 1;
            sub_elements[1] = 1;
            elements_in_sub = 2;

            /* Row Data */
            reader = 0;
            do {
                if (((symbol->option_2 & 1) || (current_row & 1)) ||
                        ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
                        (((current_row * symbol->option_2) - codeblocks) & 1))) {
                    /* left to right */
                    left_to_right = 1;
                    i = 2 + (current_block * 21);
                    for (j = 0; j < 21; j++) {
                        if ((i + j) < pattern_width) {
                            sub_elements[j + (reader * 21) + 2] = elements[i + j];

                            elements_in_sub++;
                        }
                    }
                } else {
                    /* right to left */
                    left_to_right = 0;
                    if ((current_row * symbol->option_2) < codeblocks) {
                        /* a full row */
                        i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21);
                        for (j = 0; j < 21; j++) {
                            if ((i + j) < pattern_width) {
                                sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j];
                                elements_in_sub++;
                            }
                        }
                    } else {
                        /* a partial row */
                        k = ((current_row * symbol->option_2) - codeblocks);
                        l = (current_row * symbol->option_2) - reader - 1;
                        i = 2 + ((l - k) * 21);
                        for (j = 0; j < 21; j++) {
                            if ((i + j) < pattern_width) {
                                sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j];
                                elements_in_sub++;
                            }
                        }
                    }
                }
                reader++;
                current_block++;
            } while ((reader < symbol->option_2) && (current_block < codeblocks));

            /* Row Stop */
            sub_elements[elements_in_sub] = 1;
            sub_elements[elements_in_sub + 1] = 1;
            elements_in_sub += 2;

            latch = current_row & 1 ? '0' : '1';

            if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
                    (((current_row * symbol->option_2) - codeblocks) & 1)) {
                /* Special case bottom row */
                special_case_row = 1;
                sub_elements[0] = 2;
                latch = '0';
            }

            writer = 0;







|














|
>
|
|
<
|


<
<
|
|
|

<
|
<
<
<
<
<
<
<
<
<
|
<
<







|






|







2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348

2349
2350
2351


2352
2353
2354
2355

2356









2357


2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
        for (current_row = 1; current_row <= stack_rows; current_row++) {
            for (i = 0; i < 235; i++) {
                sub_elements[i] = 0;
            }
            special_case_row = 0;

            /* Row Start */
            sub_elements[0] = 1; // left guard
            sub_elements[1] = 1;
            elements_in_sub = 2;

            /* Row Data */
            reader = 0;
            do {
                if (((symbol->option_2 & 1) || (current_row & 1)) ||
                        ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
                        (((current_row * symbol->option_2) - codeblocks) & 1))) {
                    /* left to right */
                    left_to_right = 1;
                    i = 2 + (current_block * 21);
                    for (j = 0; j < 21; j++) {
                        if ((i + j) < pattern_width) {
                                sub_elements[j + (reader * 21) + 2] = elements[i + j];
                        }
                        elements_in_sub++;
                    }

                } else { 
                    /* right to left */
                    left_to_right = 0;


                    i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21);
                    for (j = 0; j < 21; j++) {
                        if ((i + j) < pattern_width) {
                                sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j];

                        }









                        elements_in_sub++;


                    }
                }
                reader++;
                current_block++;
            } while ((reader < symbol->option_2) && (current_block < codeblocks));

            /* Row Stop */
            sub_elements[elements_in_sub] = 1; // right guard
            sub_elements[elements_in_sub + 1] = 1;
            elements_in_sub += 2;

            latch = current_row & 1 ? '0' : '1';

            if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
                    ((current_row & 1) == 0) && ((symbol->option_2 & 1) == 0)) {
                /* Special case bottom row */
                special_case_row = 1;
                sub_elements[0] = 2;
                latch = '0';
            }

            writer = 0;
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390



2391
2392
2393
2394
2395
2396
2397
                    } else {
                        set_module(symbol, symbol->rows - 1, j);
                    }
                }
                symbol->row_height[symbol->rows - 1] = 1;
                /* finder bar adjustment */
                for (j = 0; j < reader; j++) {
                    k = (49 * j) + (special_case_row ? 19 : 18);
                    if (left_to_right) {
                        for (i = 0; i < 15; i++) {
                            if ((!(module_is_set(symbol, symbol->rows, i + k - 1))) &&
                                    (!(module_is_set(symbol, symbol->rows, i + k))) &&
                                    module_is_set(symbol, symbol->rows - 1, i + k - 1)) {
                                unset_module(symbol, symbol->rows - 1, i + k);
                            }
                        }
                    } else {



                        for (i = 14; i >= 0; i--) {
                            if ((!(module_is_set(symbol, symbol->rows, i + k + 1))) &&
                                    (!(module_is_set(symbol, symbol->rows, i + k))) &&
                                    module_is_set(symbol, symbol->rows - 1, i + k + 1)) {
                                unset_module(symbol, symbol->rows - 1, i + k);
                            }
                        }







|









>
>
>







2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
                    } else {
                        set_module(symbol, symbol->rows - 1, j);
                    }
                }
                symbol->row_height[symbol->rows - 1] = 1;
                /* finder bar adjustment */
                for (j = 0; j < reader; j++) {
                    k = (49 * j) + 18 + special_case_row;
                    if (left_to_right) {
                        for (i = 0; i < 15; i++) {
                            if ((!(module_is_set(symbol, symbol->rows, i + k - 1))) &&
                                    (!(module_is_set(symbol, symbol->rows, i + k))) &&
                                    module_is_set(symbol, symbol->rows - 1, i + k - 1)) {
                                unset_module(symbol, symbol->rows - 1, i + k);
                            }
                        }
                    } else {
                        if ((current_row == stack_rows) && (data_chars % 2 == 0)) {
                            k -= 18;
                        }
                        for (i = 14; i >= 0; i--) {
                            if ((!(module_is_set(symbol, symbol->rows, i + k + 1))) &&
                                    (!(module_is_set(symbol, symbol->rows, i + k))) &&
                                    module_is_set(symbol, symbol->rows - 1, i + k + 1)) {
                                unset_module(symbol, symbol->rows - 1, i + k);
                            }
                        }
2453
2454
2455
2456
2457
2458
2459






2460
2461
2462
                        unset_module(symbol, separator_row, i + k);
                    }
                }
            }
        }

    }







    return 0;
}







>
>
>
>
>
>



2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
                        unset_module(symbol, separator_row, i + k);
                    }
                }
            }
        }

    }
    
    for (i = 0; i < symbol->rows; i++) {
        if (symbol->row_height[i] == 0) {
            symbol->row_height[i] = 34;
        }
    }

    return 0;
}
Added jni/zint/backend/stdint_msvc.h.








































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*  stdint_msvc.h - definitions for libzint

    libzint - the open source barcode library
    Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
 */

#ifndef STDINT_MSVC_H
#define STDINT_MSVC_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#ifdef _MSC_VER

typedef BYTE uint8_t;
typedef WORD uint16_t;
typedef DWORD uint32_t;
typedef INT32 int32_t;

#endif

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* STDINT_MSVC_H */
Changes to jni/zint/backend/svg.c.
31
32
33
34
35
36
37




38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54





55
56
57
58
59
60
61
62































63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
 */

#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>




#include "common.h"

#define SSET	"0123456789ABCDEF"

int svg_plot(struct zint_symbol *symbol) {
    int i, block_width, latch, r, this_row;
    float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0;
    FILE *fsvg;
    int error_number = 0;
    int textoffset, xoffset, yoffset, textdone, main_width;
    char textpart[10], addon[6];
    int large_bar_count, comp_offset;
    float addon_text_posn;
    float scaler = symbol->scale;
    float default_text_posn;
    int plot_text = 1;
    const char *locale = NULL;






    row_height = 0;
    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;
































    if ((symbol->output_options & BARCODE_STDOUT) != 0) {
        fsvg = stdout;
    } else {
        fsvg = fopen(symbol->outfile, "w");
    }
    if (fsvg == NULL) {
        strcpy(symbol->errtxt, "Could not open output file");
        return ZINT_ERROR_FILE_ACCESS;
    }

    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");

        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target");

        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target");

        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target");

        return ZINT_ERROR_INVALID_OPTION;
    }
    locale = setlocale(LC_ALL, "C");

    if (symbol->height == 0) {
        symbol->height = 50;
    }







>
>
>
>















<

>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|





|








|
>



|
>




|
>




|
>







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
 */

#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif

#include "common.h"

#define SSET	"0123456789ABCDEF"

int svg_plot(struct zint_symbol *symbol) {
    int i, block_width, latch, r, this_row;
    float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0;
    FILE *fsvg;
    int error_number = 0;
    int textoffset, xoffset, yoffset, textdone, main_width;
    char textpart[10], addon[6];
    int large_bar_count, comp_offset;
    float addon_text_posn;
    float scaler = symbol->scale;
    float default_text_posn;

    const char *locale = NULL;
#ifndef _MSC_VER
    unsigned char local_text[ustrlen(symbol->text) + 1];
#else
    unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1);
#endif

    row_height = 0;
    textdone = 0;
    main_width = symbol->width;
    strcpy(addon, "");
    comp_offset = 0;
    addon_text_posn = 0.0;

    if (symbol->show_hrt != 0) {
        /* Copy text from symbol */
        ustrcpy(local_text, symbol->text);
    } else {
        /* No text needed */
        switch (symbol->symbology) {
            case BARCODE_EANX:
            case BARCODE_EANX_CC:
            case BARCODE_ISBNX:
            case BARCODE_UPCA:
            case BARCODE_UPCE:
            case BARCODE_UPCA_CC:
            case BARCODE_UPCE_CC:
                /* For these symbols use dummy text to ensure formatting is done
                 * properly even if no text is required */
                for (i = 0; i < ustrlen(symbol->text); i++) {
                    if (symbol->text[i] == '+') {
                        local_text[i] = '+';
                    } else {
                        local_text[i] = ' ';
                    }
                    local_text[ustrlen(symbol->text)] = '\0';
                }
                break;
            default:
                /* For everything else, just remove the text */
                local_text[0] = '\0';
                break;
        }
    }

    if (symbol->output_options & BARCODE_STDOUT) {
        fsvg = stdout;
    } else {
        fsvg = fopen(symbol->outfile, "w");
    }
    if (fsvg == NULL) {
        strcpy(symbol->errtxt, "Could not open output file (F60)");
        return ZINT_ERROR_FILE_ACCESS;
    }

    /* sort out colour options */
    to_upper((unsigned char*) symbol->fgcolour);
    to_upper((unsigned char*) symbol->bgcolour);

    if (strlen(symbol->fgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F61)");
        fclose(fsvg);
        return ZINT_ERROR_INVALID_OPTION;
    }
    if (strlen(symbol->bgcolour) != 6) {
        strcpy(symbol->errtxt, "Malformed background colour target (F62)");
        fclose(fsvg);
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed foreground colour target (F63)");
        fclose(fsvg);
        return ZINT_ERROR_INVALID_OPTION;
    }
    error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour));
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Malformed background colour target (F64)");
        fclose(fsvg);
        return ZINT_ERROR_INVALID_OPTION;
    }
    locale = setlocale(LC_ALL, "C");

    if (symbol->height == 0) {
        symbol->height = 50;
    }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(symbol->text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) {
        comp_offset++;
    }

    /* Certain symbols need whitespace otherwise characters get chopped off the sides */
    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC))
            || (symbol->symbology == BARCODE_ISBNX)) {
        switch (ustrlen(local_text)) {
            case 13: /* EAN 13 */
            case 16:
            case 19:
                if (symbol->whitespace_width == 0) {
                    symbol->whitespace_width = 10;
                }
                main_width = 96 + comp_offset;
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(symbol->text); i++) {
            if (latch == 1) {
                addon[r] = symbol->text[i];
                r++;
            }
            if (symbol->text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';

    if ((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) {
        plot_text = 0;
    }
    if (plot_text) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }
    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;

    /* Start writing the header */
    fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
    fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
    fprintf(fsvg, "   \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int)ceil((symbol->width + xoffset + xoffset) * scaler), (int)ceil((symbol->height + textoffset + yoffset + yoffset) * scaler));
    } else {
        fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int)ceil((74.0F + xoffset + xoffset) * scaler), (int)ceil((72.0F + yoffset + yoffset) * scaler));
    }
    fprintf(fsvg, "   xmlns=\"http://www.w3.org/2000/svg\">\n");
    if (ustrlen(symbol->text) != 0) {
        fprintf(fsvg, "   <desc>%s\n", symbol->text);
    } else {
        fprintf(fsvg, "   <desc>Zint Generated Symbol\n");
    }
    fprintf(fsvg, "   </desc>\n");
    fprintf(fsvg, "\n   <g id=\"barcode\" fill=\"#%s\">\n", symbol->fgcolour);

    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(fsvg, "      <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", (int)ceil((symbol->width + xoffset + xoffset) * scaler), (int)ceil((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour);
    } else {
        fprintf(fsvg, "      <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", (int)ceil((74.0F + xoffset + xoffset) * scaler), (int)ceil((72.0F + yoffset + yoffset) * scaler), symbol->bgcolour);
    }

    if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
        default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler;
    } else {
        default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler;
    }

    if (symbol->symbology == BARCODE_MAXICODE) {
        /* Maxicode uses hexagons */
        float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my;


        textoffset = 0.0;
        if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler);
        }
        if ((symbol->output_options & BARCODE_BOX) != 0) {
            /* side bars */
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler);
        }
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour);
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour);
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour);







|

|


|






<
<
<
|












|

|


|
|







|

|


|











|



|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
        }
    }

    latch = 0;
    r = 0;
    /* Isolate add-on text */
    if (is_extendable(symbol->symbology)) {
        for (i = 0; i < ustrlen(local_text); i++) {
            if (latch == 1) {
                addon[r] = local_text[i];
                r++;
            }
            if (local_text[i] == '+') {
                latch = 1;
            }
        }
    }
    addon[r] = '\0';




    if (ustrlen(local_text) != 0) {
        textoffset = 9;
    } else {
        textoffset = 0;
    }
    xoffset = symbol->border_width + symbol->whitespace_width;
    yoffset = symbol->border_width;

    /* Start writing the header */
    fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
    fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
    fprintf(fsvg, "   \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int) ceil((symbol->width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler));
    } else {
        fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int) ceil((74.0F + xoffset + xoffset) * scaler), (int) ceil((72.0F + yoffset + yoffset) * scaler));
    }
    fprintf(fsvg, "   xmlns=\"http://www.w3.org/2000/svg\">\n");
    if ((ustrlen(local_text) != 0) && (symbol->show_hrt != 0)) {
        fprintf(fsvg, "   <desc>%s\n", local_text);
    } else {
        fprintf(fsvg, "   <desc>Zint Generated Symbol\n");
    }
    fprintf(fsvg, "   </desc>\n");
    fprintf(fsvg, "\n   <g id=\"barcode\" fill=\"#%s\">\n", symbol->fgcolour);

    if (symbol->symbology != BARCODE_MAXICODE) {
        fprintf(fsvg, "      <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", (int) ceil((symbol->width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour);
    } else {
        fprintf(fsvg, "      <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", (int) ceil((74.0F + xoffset + xoffset) * scaler), (int) ceil((72.0F + yoffset + yoffset) * scaler), symbol->bgcolour);
    }

    if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
        default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler;
    } else {
        default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler;
    }

    if (symbol->symbology == BARCODE_MAXICODE) {
        /* Maxicode uses hexagons */
        float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my;


        textoffset = 0.0;
        if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler);
        }
        if (symbol->output_options & BARCODE_BOX) {
            /* side bars */
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler);
        }
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour);
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour);
        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour);
271
272
273
274
275
276
277









278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576





577
578
579
580

581
582



583

584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
                    row_posn += large_bar_height;
                } else {
                    row_posn += symbol->row_height[i];
                }
            }
            row_posn += yoffset;










            i = 0;
            if (module_is_set(symbol, this_row, 0)) {
                latch = 1;
            } else {
                latch = 0;
            }

            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
                if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) {
                    addon_text_posn = (row_posn + 8.0) * scaler;
                    addon_latch = 1;
                }
                if (latch == 1) {
                    /* a bar */
                    if (addon_latch == 0) {
                        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler);
                    } else {
                        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler);
                    }
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;

            } while (i < symbol->width);

        }
    }
    /* That's done the actual data area, everything else is human-friendly */

    xoffset += comp_offset;
    row_posn = (row_posn + large_bar_height) * scaler;

    if (plot_text) {
        if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) ||
                (symbol->symbology == BARCODE_ISBNX)) {
            /* guard bar extensions and text formatting for EAN8 and EAN13 */
            switch (ustrlen(symbol->text)) {
                case 8: /* EAN-8 */
                case 11:
                case 14:
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    for (i = 0; i < 4; i++) {
                        textpart[i] = symbol->text[i];
                    }
                    textpart[4] = '\0';
                    textpos = 17;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", textpart);
                    fprintf(fsvg, "      </text>\n");
                    for (i = 0; i < 4; i++) {
                        textpart[i] = symbol->text[i + 4];
                    }
                    textpart[4] = '\0';
                    textpos = 50;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", textpart);
                    fprintf(fsvg, "      </text>\n");
                    textdone = 1;
                    switch (strlen(addon)) {
                        case 2:
                            textpos = xoffset + 86;
                            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                            fprintf(fsvg, "         %s\n", addon);
                            fprintf(fsvg, "      </text>\n");
                            break;
                        case 5:
                            textpos = xoffset + 100;
                            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                            fprintf(fsvg, "         %s\n", addon);
                            fprintf(fsvg, "      </text>\n");
                            break;
                    }

                    break;
                case 13: /* EAN 13 */
                case 16:
                case 19:
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                    textpart[0] = symbol->text[0];
                    textpart[1] = '\0';
                    textpos = -7;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", textpart);
                    fprintf(fsvg, "      </text>\n");
                    for (i = 0; i < 6; i++) {
                        textpart[i] = symbol->text[i + 1];
                    }
                    textpart[6] = '\0';
                    textpos = 24;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", textpart);
                    fprintf(fsvg, "      </text>\n");
                    for (i = 0; i < 6; i++) {
                        textpart[i] = symbol->text[i + 7];
                    }
                    textpart[6] = '\0';
                    textpos = 71;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", textpart);
                    fprintf(fsvg, "      </text>\n");
                    textdone = 1;
                    switch (strlen(addon)) {
                        case 2:
                            textpos = xoffset + 114;
                            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                            fprintf(fsvg, "         %s\n", addon);
                            fprintf(fsvg, "      </text>\n");
                            break;
                        case 5:
                            textpos = xoffset + 128;
                            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                            fprintf(fsvg, "         %s\n", addon);
                            fprintf(fsvg, "      </text>\n");
                            break;
                    }
                    break;

            }
        }

        if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
            /* guard bar extensions and text formatting for UPCA */
            latch = 1;

            i = 0 + comp_offset;
            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
                if (latch == 1) {
                    /* a bar */
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler);
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;
            } while (i < 11 + comp_offset);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            latch = 1;
            i = 85 + comp_offset;
            do {
                block_width = 0;
                do {
                    block_width++;
                } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
                if (latch == 1) {
                    /* a bar */
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler);
                    latch = 0;
                } else {
                    /* a space */
                    latch = 1;
                }
                i += block_width;
            } while (i < 96 + comp_offset);
            textpart[0] = symbol->text[0];
            textpart[1] = '\0';
            textpos = -5;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            for (i = 0; i < 5; i++) {
                textpart[i] = symbol->text[i + 1];
            }
            textpart[5] = '\0';
            textpos = 27;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            for (i = 0; i < 5; i++) {
                textpart[i] = symbol->text[i + 6];
            }
            textpart[6] = '\0';
            textpos = 68;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            textpart[0] = symbol->text[11];
            textpart[1] = '\0';
            textpos = 100;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            textdone = 1;
            switch (strlen(addon)) {
                case 2:
                    textpos = xoffset + 116;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", addon);
                    fprintf(fsvg, "      </text>\n");
                    break;
                case 5:
                    textpos = xoffset + 130;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", addon);
                    fprintf(fsvg, "      </text>\n");
                    break;
            }

        }

        if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
            /* guard bar extensions and text formatting for UPCE */
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
            textpart[0] = symbol->text[0];
            textpart[1] = '\0';
            textpos = -5;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            for (i = 0; i < 6; i++) {
                textpart[i] = symbol->text[i + 1];
            }
            textpart[6] = '\0';
            textpos = 24;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            textpart[0] = symbol->text[7];
            textpart[1] = '\0';
            textpos = 55;
            fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
            fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
            fprintf(fsvg, "         %s\n", textpart);
            fprintf(fsvg, "      </text>\n");
            textdone = 1;
            switch (strlen(addon)) {
                case 2:
                    textpos = xoffset + 70;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", addon);
                    fprintf(fsvg, "      </text>\n");
                    break;
                case 5:
                    textpos = xoffset + 84;
                    fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                    fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                    fprintf(fsvg, "         %s\n", addon);
                    fprintf(fsvg, "      </text>\n");
                    break;
            }

        }
    } /* if (plot_text) */

    xoffset -= comp_offset;

    switch (symbol->symbology) {
        case BARCODE_MAXICODE:
            /* Do nothing! (It's already been done) */
            break;
        default:
            if ((symbol->output_options & BARCODE_BIND) != 0) {
                if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                    /* row binding */

                    for (r = 1; r < symbol->rows; r++) {
                        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler);





                    }
                }
            }
            if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {

                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);



            }

            if ((symbol->output_options & BARCODE_BOX) != 0) {
                /* side bars */
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
            }
            break;
    }

    /* Put the human readable text at the bottom */
    if (plot_text && (textdone == 0)) {
        textpos = symbol->width / 2.0;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", symbol->text);
        fprintf(fsvg, "      </text>\n");
    }
    fprintf(fsvg, "   </g>\n");
    fprintf(fsvg, "</svg>\n");

    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(fsvg);







>
>
>
>
>
>
>
>
>
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
>







<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
<








|


>
|
|
>
>
>
>
>



|
>
|
|
>
>
>
|
>
|








|



|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
                    row_posn += large_bar_height;
                } else {
                    row_posn += symbol->row_height[i];
                }
            }
            row_posn += yoffset;

            if (symbol->output_options & BARCODE_DOTTY_MODE) {
                /* Use (currently undocumented) dot mode - see SF ticket #29 */
                for (i = 0; i < symbol->width; i++) {
                    if (module_is_set(symbol, this_row, i)) {
                        fprintf(fsvg, "      <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", ((i + xoffset) * scaler) + (scaler / 2.0), (row_posn * scaler) + (scaler / 2.0), (symbol->dot_size / 2.0) * scaler, symbol->fgcolour);
                    }
                }
            } else {
                /* Normal mode, with rectangles */
                i = 0;
                if (module_is_set(symbol, this_row, 0)) {
                    latch = 1;
                } else {
                    latch = 0;
                }

                do {
                    block_width = 0;
                    do {
                        block_width++;
                    } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
                    if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) {
                        addon_text_posn = (row_posn + 8.0) * scaler;
                        addon_latch = 1;
                    }
                    if (latch == 1) {
                        /* a bar */
                        if (addon_latch == 0) {
                            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler);
                        } else {
                            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler);
                        }
                        latch = 0;
                    } else {
                        /* a space */
                        latch = 1;
                    }
                    i += block_width;

                } while (i < symbol->width);
            }
        }
    }
    /* That's done the actual data area, everything else is human-friendly */

    xoffset += comp_offset;
    row_posn = (row_posn + large_bar_height) * scaler;


    if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) ||
            (symbol->symbology == BARCODE_ISBNX)) {
        /* guard bar extensions and text formatting for EAN8 and EAN13 */
        switch (ustrlen(local_text)) {
            case 8: /* EAN-8 */
            case 11:
            case 14:
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i];
                }
                textpart[4] = '\0';
                textpos = 17;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", textpart);
                fprintf(fsvg, "      </text>\n");
                for (i = 0; i < 4; i++) {
                    textpart[i] = local_text[i + 4];
                }
                textpart[4] = '\0';
                textpos = 50;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", textpart);
                fprintf(fsvg, "      </text>\n");
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = xoffset + 86;
                        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                        fprintf(fsvg, "         %s\n", addon);
                        fprintf(fsvg, "      </text>\n");
                        break;
                    case 5:
                        textpos = xoffset + 100;
                        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                        fprintf(fsvg, "         %s\n", addon);
                        fprintf(fsvg, "      </text>\n");
                        break;
                }

                break;
            case 13: /* EAN 13 */
            case 16:
            case 19:
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
                textpart[0] = local_text[0];
                textpart[1] = '\0';
                textpos = -7;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", textpart);
                fprintf(fsvg, "      </text>\n");
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 1];
                }
                textpart[6] = '\0';
                textpos = 24;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", textpart);
                fprintf(fsvg, "      </text>\n");
                for (i = 0; i < 6; i++) {
                    textpart[i] = local_text[i + 7];
                }
                textpart[6] = '\0';
                textpos = 71;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", textpart);
                fprintf(fsvg, "      </text>\n");
                textdone = 1;
                switch (strlen(addon)) {
                    case 2:
                        textpos = xoffset + 114;
                        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                        fprintf(fsvg, "         %s\n", addon);
                        fprintf(fsvg, "      </text>\n");
                        break;
                    case 5:
                        textpos = xoffset + 128;
                        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                        fprintf(fsvg, "         %s\n", addon);
                        fprintf(fsvg, "      </text>\n");
                        break;
                }
                break;

        }
    }

    if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
        /* guard bar extensions and text formatting for UPCA */
        latch = 1;

        i = 0 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 11 + comp_offset);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        latch = 1;
        i = 85 + comp_offset;
        do {
            block_width = 0;
            do {
                block_width++;
            } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
            if (latch == 1) {
                /* a bar */
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler);
                latch = 0;
            } else {
                /* a space */
                latch = 1;
            }
            i += block_width;
        } while (i < 96 + comp_offset);
        textpart[0] = local_text[0];
        textpart[1] = '\0';
        textpos = -5;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[5] = '\0';
        textpos = 27;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        for (i = 0; i < 5; i++) {
            textpart[i] = local_text[i + 6];
        }
        textpart[6] = '\0';
        textpos = 68;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        textpart[0] = local_text[11];
        textpart[1] = '\0';
        textpos = 100;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = xoffset + 116;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", addon);
                fprintf(fsvg, "      </text>\n");
                break;
            case 5:
                textpos = xoffset + 130;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", addon);
                fprintf(fsvg, "      </text>\n");
                break;
        }

    }

    if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
        /* guard bar extensions and text formatting for UPCE */
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler);
        textpart[0] = local_text[0];
        textpart[1] = '\0';
        textpos = -5;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        for (i = 0; i < 6; i++) {
            textpart[i] = local_text[i + 1];
        }
        textpart[6] = '\0';
        textpos = 24;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        textpart[0] = local_text[7];
        textpart[1] = '\0';
        textpos = 55;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", textpart);
        fprintf(fsvg, "      </text>\n");
        textdone = 1;
        switch (strlen(addon)) {
            case 2:
                textpos = xoffset + 70;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", addon);
                fprintf(fsvg, "      </text>\n");
                break;
            case 5:
                textpos = xoffset + 84;
                fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", textpos * scaler, addon_text_posn * scaler);
                fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 11.0 * scaler, symbol->fgcolour);
                fprintf(fsvg, "         %s\n", addon);
                fprintf(fsvg, "      </text>\n");
                break;
        }

    }


    xoffset -= comp_offset;

    switch (symbol->symbology) {
        case BARCODE_MAXICODE:
            /* Do nothing! (It's already been done) */
            break;
        default:
            if (symbol->output_options & BARCODE_BIND) {
                if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
                    /* row binding */
                    if (symbol->symbology != BARCODE_CODABLOCKF) {
                        for (r = 1; r < symbol->rows; r++) {
                            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler);
                        }
                    } else {
                        for (r = 1; r < symbol->rows; r++) {
                            fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (xoffset + 11) * scaler, ((r * row_height) + yoffset - 1) * scaler, (symbol->width - 25) * scaler, 2.0 * scaler);
                        }
                    }
                }
            }
            if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
                if (symbol->symbology != BARCODE_CODABLOCKF) {
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
                } else {
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", xoffset * scaler, 0.0, symbol->width * scaler, symbol->border_width * scaler);
                    fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", xoffset * scaler, (symbol->height + symbol->border_width) * scaler, symbol->width * scaler, symbol->border_width * scaler);
                }
            }
            if (symbol->output_options & BARCODE_BOX) {
                /* side bars */
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
                fprintf(fsvg, "      <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
            }
            break;
    }

    /* Put the human readable text at the bottom */
    if ((textdone == 0) && ustrlen(local_text)) {
        textpos = symbol->width / 2.0;
        fprintf(fsvg, "      <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", (textpos + xoffset) * scaler, default_text_posn);
        fprintf(fsvg, "         font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", 8.0 * scaler, symbol->fgcolour);
        fprintf(fsvg, "         %s\n", local_text);
        fprintf(fsvg, "      </text>\n");
    }
    fprintf(fsvg, "   </g>\n");
    fprintf(fsvg, "</svg>\n");

    if (symbol->output_options & BARCODE_STDOUT) {
        fflush(fsvg);
Changes to jni/zint/backend/telepen.c.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    char dest[512]; /*14 + 30 * 14 + 14 + 14 + 1 ~ 512 */

    error_number = 0;

    count = 0;

    if (src_len > 30) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    /* Start character */
    strcpy(dest, TeleTable['_']);

    for (i = 0; i < src_len; i++) {
        if (source[i] > 126) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat(dest, TeleTable[source[i]]);
        count += source[i];
    }

    check_digit = 127 - (count % 127);







|








|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    char dest[512]; /*14 + 30 * 14 + 14 + 14 + 1 ~ 512 */

    error_number = 0;

    count = 0;

    if (src_len > 30) {
        strcpy(symbol->errtxt, "Input too long (C90)");
        return ZINT_ERROR_TOO_LONG;
    }
    /* Start character */
    strcpy(dest, TeleTable['_']);

    for (i = 0; i < src_len; i++) {
        if (source[i] > 126) {
            /* Cannot encode extended ASCII */
            strcpy(symbol->errtxt, "Invalid characters in input data (C91)");
            return ZINT_ERROR_INVALID_DATA;
        }
        strcat(dest, TeleTable[source[i]]);
        count += source[i];
    }

    check_digit = 127 - (count % 127);
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

int telepen_num(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    unsigned int i, count, check_digit, glyph;
    int error_number, temp_length = src_len;
    char dest[1024]; /* 14 + 60 * 14 + 14 + 14 + 1 ~ 1024 */
    unsigned char temp[64];

    error_number = 0;
    count = 0;

    if (temp_length > 60) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    ustrcpy(temp, source);
    to_upper(temp);
    error_number = is_sane(NEON, temp, temp_length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data");
        return error_number;
    }

    /* Add a leading zero if required */
    if (temp_length & 1) {
        memmove(temp + 1, temp, temp_length);
        temp[0] = '0';

        temp[++temp_length] = '\0';
    }

    /* Start character */
    strcpy(dest, TeleTable['_']);

    for (i = 0; i < temp_length; i += 2) {
        if (temp[i] == 'X') {
            strcpy(symbol->errtxt, "Invalid position of X in Telepen data");
            return ZINT_ERROR_INVALID_DATA;
        }

        if (temp[i + 1] == 'X') {
            glyph = ctoi(temp[i]) + 17;
            count += glyph;
        } else {







<



|






|
















|







105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

int telepen_num(struct zint_symbol *symbol, unsigned char source[], int src_len) {
    unsigned int i, count, check_digit, glyph;
    int error_number, temp_length = src_len;
    char dest[1024]; /* 14 + 60 * 14 + 14 + 14 + 1 ~ 1024 */
    unsigned char temp[64];


    count = 0;

    if (temp_length > 60) {
        strcpy(symbol->errtxt, "Input too long (C92)");
        return ZINT_ERROR_TOO_LONG;
    }
    ustrcpy(temp, source);
    to_upper(temp);
    error_number = is_sane(NEON, temp, temp_length);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in data (C93)");
        return error_number;
    }

    /* Add a leading zero if required */
    if (temp_length & 1) {
        memmove(temp + 1, temp, temp_length);
        temp[0] = '0';

        temp[++temp_length] = '\0';
    }

    /* Start character */
    strcpy(dest, TeleTable['_']);

    for (i = 0; i < temp_length; i += 2) {
        if (temp[i] == 'X') {
            strcpy(symbol->errtxt, "Invalid position of X in Telepen data (C94)");
            return ZINT_ERROR_INVALID_DATA;
        }

        if (temp[i + 1] == 'X') {
            glyph = ctoi(temp[i]) + 17;
            count += glyph;
        } else {
Changes to jni/zint/backend/upcean.c.
120
121
122
123
124
125
126
127
128
129
130
131
132


133
134








135
136

137
138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
























166
167
168
169
170
171
172
    }

    /* stop character */
    strcat(dest, "111");
}

/* Make a UPC A barcode when we haven't been given the check digit */
void upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    int length;
    char gtin[15];

    strcpy(gtin, (char*) source);
    length = strlen(gtin);


    gtin[length] = upc_check(gtin);
    gtin[length + 1] = '\0';








    upca_draw(gtin, dest);
    ustrcpy(symbol->text, (unsigned char*) gtin);

}

/* UPC E is a zero-compressed version of UPC A */
void upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    unsigned int i, num_system;
    char emode, equivalent[12], check_digit, parity[8], temp[8];
    char hrt[9];

    /* Two number systems can be used - system 0 and system 1 */


    if (ustrlen(source) == 7) {
        switch (source[0]) {
            case '0': num_system = 0;
                break;
            case '1': num_system = 1;
                break;
            default: num_system = 0;
                source[0] = '0';
                break;
        }
        strcpy(temp, (char*) source);
        strcpy(hrt, (char*) source);
        for (i = 1; i <= 7; i++) {
            source[i - 1] = temp[i];
        }
    } else {
        num_system = 0;
        hrt[0] = '0';
        hrt[1] = '\0';
        strcat(hrt, (char*) source);
























    }

    /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */
    emode = source[5];
    for (i = 0; i < 11; i++) {
        equivalent[i] = '0';
    }







|





>
>
|
|
>
>
>
>
>
>
>
>


>



|





>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    }

    /* stop character */
    strcat(dest, "111");
}

/* Make a UPC A barcode when we haven't been given the check digit */
int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    int length;
    char gtin[15];

    strcpy(gtin, (char*) source);
    length = strlen(gtin);
    
    if (length == 11) {
        gtin[length] = upc_check(gtin);
        gtin[length + 1] = '\0';
    } else {
        gtin[length - 1] = '\0';
        if (source[length - 1] != upc_check(gtin)) {
            strcpy(symbol->errtxt, "Invalid check digit (C60)");
            return ZINT_ERROR_INVALID_DATA;
        }
        gtin[length - 1] = upc_check(gtin);
    }
    upca_draw(gtin, dest);
    ustrcpy(symbol->text, (unsigned char*) gtin);
    return 0;
}

/* UPC E is a zero-compressed version of UPC A */
int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    unsigned int i, num_system;
    char emode, equivalent[12], check_digit, parity[8], temp[8];
    char hrt[9];

    /* Two number systems can be used - system 0 and system 1 */
    if (symbol->symbology != BARCODE_UPCE_CHK) {
        /* No check digit in input data */
        if (ustrlen(source) == 7) {
            switch (source[0]) {
                case '0': num_system = 0;
                    break;
                case '1': num_system = 1;
                    break;
                default: num_system = 0;
                    source[0] = '0';
                    break;
            }
            strcpy(temp, (char*) source);
            strcpy(hrt, (char*) source);
            for (i = 1; i <= 7; i++) {
                source[i - 1] = temp[i];
            }
        } else {
            num_system = 0;
            hrt[0] = '0';
            hrt[1] = '\0';
            strcat(hrt, (char*) source);
        }
    } else {
        /* Check digit is included in input data */
        if (ustrlen(source) == 8) {
            switch (source[0]) {
                case '0': num_system = 0;
                    break;
                case '1': num_system = 1;
                    break;
                default: num_system = 0;
                    source[0] = '0';
                    break;
            }
            strcpy(temp, (char*) source);
            strcpy(hrt, (char*) source);
            for (i = 1; i <= 7; i++) {
                source[i - 1] = temp[i];
            }
        } else {
            num_system = 0;
            hrt[0] = '0';
            hrt[1] = '\0';
            strcat(hrt, (char*) source);
        }
    }

    /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */
    emode = source[5];
    for (i = 0; i < 11; i++) {
        equivalent[i] = '0';
    }
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
            break;
        case '3':
            equivalent[3] = source[2];
            equivalent[9] = source[3];
            equivalent[10] = source[4];
            if (((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) {
                /* Note 1 - "X3 shall not be equal to 0, 1 or 2" */
                strcpy(symbol->errtxt, "Invalid UPC-E data");

            }
            break;
        case '4':
            equivalent[3] = source[2];
            equivalent[4] = source[3];
            equivalent[10] = source[4];
            if (source[3] == '0') {
                /* Note 2 - "X4 shall not be equal to 0" */
                strcpy(symbol->errtxt, "Invalid UPC-E data");

            }
            break;
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            equivalent[3] = source[2];
            equivalent[4] = source[3];
            equivalent[5] = source[4];
            equivalent[10] = emode;
            if (source[4] == '0') {
                /* Note 3 - "X5 shall not be equal to 0" */
                strcpy(symbol->errtxt, "Invalid UPC-E data");

            }
            break;
    }

    /* Get the check digit from the expanded UPCA code */

    check_digit = upc_check(equivalent);







|
>








|
>













|
>







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
            break;
        case '3':
            equivalent[3] = source[2];
            equivalent[9] = source[3];
            equivalent[10] = source[4];
            if (((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) {
                /* Note 1 - "X3 shall not be equal to 0, 1 or 2" */
                strcpy(symbol->errtxt, "Invalid UPC-E data (C61)");
                return ZINT_ERROR_INVALID_DATA;
            }
            break;
        case '4':
            equivalent[3] = source[2];
            equivalent[4] = source[3];
            equivalent[10] = source[4];
            if (source[3] == '0') {
                /* Note 2 - "X4 shall not be equal to 0" */
                strcpy(symbol->errtxt, "Invalid UPC-E data (C62)");
                return ZINT_ERROR_INVALID_DATA;
            }
            break;
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            equivalent[3] = source[2];
            equivalent[4] = source[3];
            equivalent[5] = source[4];
            equivalent[10] = emode;
            if (source[4] == '0') {
                /* Note 3 - "X5 shall not be equal to 0" */
                strcpy(symbol->errtxt, "Invalid UPC-E data (C63)");
                return ZINT_ERROR_INVALID_DATA;
            }
            break;
    }

    /* Get the check digit from the expanded UPCA code */

    check_digit = upc_check(equivalent);
244
245
246
247
248
249
250

251
252






253

254
255
256
257
258
259
260
                break;
        }
    }

    /* stop character */
    strcat(dest, "111111");


    hrt[7] = check_digit;
    hrt[8] = '\0';






    ustrcpy(symbol->text, (unsigned char*) hrt);

}

/* EAN-2 and EAN-5 add-on codes */
void add_on(unsigned char source[], char dest[], int mode) {
    char parity[6];
    unsigned int i, code_type;








>
|
|
>
>
>
>
>
>

>







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
                break;
        }
    }

    /* stop character */
    strcat(dest, "111111");

    if (symbol->symbology != BARCODE_UPCE_CHK) {
        hrt[7] = check_digit;
        hrt[8] = '\0';
    } else {
        if (hrt[7] != check_digit) {
            strcpy(symbol->errtxt, "Invalid check digit (C64)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }
    ustrcpy(symbol->text, (unsigned char*) hrt);
    return 0;
}

/* EAN-2 and EAN-5 add-on codes */
void add_on(unsigned char source[], char dest[], int mode) {
    char parity[6];
    unsigned int i, code_type;

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347


348
349








350
351
352
353
354
355
356
    check_digit = 10 - (count % 10);
    if (check_digit == 10) {
        check_digit = 0;
    }
    return itoc(check_digit);
}

void ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    unsigned int length, i, half_way;
    char parity[6];
    char gtin[15];

    strcpy(parity, "");
    strcpy(gtin, (char*) source);

    /* Add the appropriate check digit */
    length = strlen(gtin);


    gtin[length] = ean_check(gtin);
    gtin[length + 1] = '\0';









    /* Get parity for first half of the symbol */
    lookup(SODIUM, EAN13Parity, gtin[0], parity);

    /* Now get on with the cipher */
    half_way = 7;








|









>
>
|
|
>
>
>
>
>
>
>
>







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    check_digit = 10 - (count % 10);
    if (check_digit == 10) {
        check_digit = 0;
    }
    return itoc(check_digit);
}

int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    unsigned int length, i, half_way;
    char parity[6];
    char gtin[15];

    strcpy(parity, "");
    strcpy(gtin, (char*) source);

    /* Add the appropriate check digit */
    length = strlen(gtin);
    
    if (length == 12) {
        gtin[length] = ean_check(gtin);
        gtin[length + 1] = '\0';
    } else {
        gtin[length - 1] = '\0';
        if (source[length - 1] != ean_check(gtin)) {
            strcpy(symbol->errtxt, "Invalid check digit (C65)");
            return ZINT_ERROR_INVALID_DATA;
        }
        gtin[length - 1] = ean_check(gtin);
    }

    /* Get parity for first half of the symbol */
    lookup(SODIUM, EAN13Parity, gtin[0], parity);

    /* Now get on with the cipher */
    half_way = 7;

371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387


388
389








390
391


392
393
394
395
396
397
398
        }
    }

    /* stop character */
    strcat(dest, "111");

    ustrcpy(symbol->text, (unsigned char*) gtin);

}

/* Make an EAN-8 barcode when we haven't been given the check digit */
void ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    /* EAN-8 is basically the same as UPC-A but with fewer digits */
    int length;
    char gtin[10];

    strcpy(gtin, (char*) source);
    length = strlen(gtin);


    gtin[length] = upc_check(gtin);
    gtin[length + 1] = '\0';








    upca_draw(gtin, dest);
    ustrcpy(symbol->text, (unsigned char*) gtin);


}

/* For ISBN(13) only */
char isbn13_check(unsigned char source[]) {
    unsigned int i, weight, sum, check, h;

    sum = 0;







>



|






>
>
|
|
>
>
>
>
>
>
>
>


>
>







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
        }
    }

    /* stop character */
    strcat(dest, "111");

    ustrcpy(symbol->text, (unsigned char*) gtin);
    return 0;
}

/* Make an EAN-8 barcode when we haven't been given the check digit */
int ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
    /* EAN-8 is basically the same as UPC-A but with fewer digits */
    int length;
    char gtin[10];

    strcpy(gtin, (char*) source);
    length = strlen(gtin);
    
    if (length == 7) {
        gtin[length] = upc_check(gtin);
        gtin[length + 1] = '\0';
    } else {
        gtin[length - 1] = '\0';
        if (source[length - 1] != upc_check(gtin)) {
            strcpy(symbol->errtxt, "Invalid check digit (C66)");
            return ZINT_ERROR_INVALID_DATA;
        }
        gtin[length - 1] = upc_check(gtin);
    }
    upca_draw(gtin, dest);
    ustrcpy(symbol->text, (unsigned char*) gtin);
    
    return 0;
}

/* For ISBN(13) only */
char isbn13_check(unsigned char source[]) {
    unsigned int i, weight, sum, check, h;

    sum = 0;
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
int isbn(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char dest[]) {
    int i, error_number;
    char check_digit;

    to_upper(source);
    error_number = is_sane("0123456789X", source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in input");
        return error_number;
    }

    /* Input must be 9, 10 or 13 characters */
    if (((src_len < 9) || (src_len > 13)) || ((src_len > 10) && (src_len < 13))) {
        strcpy(symbol->errtxt, "Input wrong length");
        return ZINT_ERROR_TOO_LONG;
    }

    if (src_len == 13) /* Using 13 character ISBN */ {
        if (!(((source[0] == '9') && (source[1] == '7')) &&
                ((source[2] == '8') || (source[2] == '9')))) {
            strcpy(symbol->errtxt, "Invalid ISBN");
            return ZINT_ERROR_INVALID_DATA;
        }

        check_digit = isbn13_check(source);
        if (source[src_len - 1] != check_digit) {
            strcpy(symbol->errtxt, "Incorrect ISBN check");
            return ZINT_ERROR_INVALID_CHECK;
        }
        source[12] = '\0';

        ean13(symbol, source, dest);
    }

    if (src_len == 10) /* Using 10 digit ISBN */ {
        check_digit = isbn_check(source);
        if (check_digit != source[src_len - 1]) {
            strcpy(symbol->errtxt, "Incorrect ISBN check");
            return ZINT_ERROR_INVALID_CHECK;
        }
        for (i = 13; i > 0; i--) {
            source[i] = source[i - 3];
        }
        source[0] = '9';
        source[1] = '7';







|





|






|





|










|







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
int isbn(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char dest[]) {
    int i, error_number;
    char check_digit;

    to_upper(source);
    error_number = is_sane("0123456789X", source, src_len);
    if (error_number == ZINT_ERROR_INVALID_DATA) {
        strcpy(symbol->errtxt, "Invalid characters in input (C67)");
        return error_number;
    }

    /* Input must be 9, 10 or 13 characters */
    if (((src_len < 9) || (src_len > 13)) || ((src_len > 10) && (src_len < 13))) {
        strcpy(symbol->errtxt, "Input wrong length (C68)");
        return ZINT_ERROR_TOO_LONG;
    }

    if (src_len == 13) /* Using 13 character ISBN */ {
        if (!(((source[0] == '9') && (source[1] == '7')) &&
                ((source[2] == '8') || (source[2] == '9')))) {
            strcpy(symbol->errtxt, "Invalid ISBN (C69)");
            return ZINT_ERROR_INVALID_DATA;
        }

        check_digit = isbn13_check(source);
        if (source[src_len - 1] != check_digit) {
            strcpy(symbol->errtxt, "Incorrect ISBN check (C6A)");
            return ZINT_ERROR_INVALID_CHECK;
        }
        source[12] = '\0';

        ean13(symbol, source, dest);
    }

    if (src_len == 10) /* Using 10 digit ISBN */ {
        check_digit = isbn_check(source);
        if (check_digit != source[src_len - 1]) {
            strcpy(symbol->errtxt, "Incorrect ISBN check (C6B)");
            return ZINT_ERROR_INVALID_CHECK;
        }
        for (i = 13; i > 0; i--) {
            source[i] = source[i - 3];
        }
        source[0] = '9';
        source[1] = '7';
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
            source[i] = source[i - 1];
        }
        source[0] = '0';

        /* Verify check digit */
        check_digit = isbn_check(source);
        if (check_digit != source[ustrlen(source) - 1]) {
            strcpy(symbol->errtxt, "Incorrect SBN check");
            return ZINT_ERROR_INVALID_CHECK;
        }

        /* Convert to EAN-13 number */
        for (i = 13; i > 0; i--) {
            source[i] = source[i - 3];
        }







|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
            source[i] = source[i - 1];
        }
        source[0] = '0';

        /* Verify check digit */
        check_digit = isbn_check(source);
        if (check_digit != source[ustrlen(source) - 1]) {
            strcpy(symbol->errtxt, "Incorrect SBN check (C6C)");
            return ZINT_ERROR_INVALID_CHECK;
        }

        /* Convert to EAN-13 number */
        for (i = 13; i > 0; i--) {
            source[i] = source[i - 3];
        }
571
572
573
574
575
576
577
















578
579
580
581
582



583
584
585
586
587
588
589
590
591








592
593
594
595
596
597
598
            if (second_len == 0) {
                if (first_len <= 5) {
                    zfirst_len = 5;
                }
                if (first_len <= 2) {
                    zfirst_len = 2;
                }
















            }
            break;
        case BARCODE_UPCA:
        case BARCODE_UPCA_CC:
            zfirst_len = 11;



            break;
        case BARCODE_UPCE:
        case BARCODE_UPCE_CC:
            if (first_len == 7) {
                zfirst_len = 7;
            }
            if (first_len <= 6) {
                zfirst_len = 6;
            }








            break;
        case BARCODE_ISBNX:
            if (first_len <= 9) {
                zfirst_len = 9;
            }
            break;
    }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>









>
>
>
>
>
>
>
>







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
            if (second_len == 0) {
                if (first_len <= 5) {
                    zfirst_len = 5;
                }
                if (first_len <= 2) {
                    zfirst_len = 2;
                }
            }
            break;
        case BARCODE_EANX_CHK:
            if (first_len <= 13) {
                zfirst_len = 13;
            }
            if (first_len <= 8) {
                zfirst_len = 8;
            }
            if (second_len == 0) {
                if (first_len <= 5) {
                    zfirst_len = 5;
                }
                if (first_len <= 2) {
                    zfirst_len = 2;
                }
            }
            break;
        case BARCODE_UPCA:
        case BARCODE_UPCA_CC:
            zfirst_len = 11;
            break;
        case BARCODE_UPCA_CHK:
            zfirst_len = 12;
            break;
        case BARCODE_UPCE:
        case BARCODE_UPCE_CC:
            if (first_len == 7) {
                zfirst_len = 7;
            }
            if (first_len <= 6) {
                zfirst_len = 6;
            }
            break;
        case BARCODE_UPCE_CHK:
            if (first_len == 8) {
                zfirst_len = 8;
            }
            if (first_len <= 7) {
                zfirst_len = 7;
            }
            break;
        case BARCODE_ISBNX:
            if (first_len <= 9) {
                zfirst_len = 9;
            }
            break;
    }
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652


    with_addon = FALSE;
    latch = FALSE;
    writer = 0;

    if (src_len > 19) {
        strcpy(symbol->errtxt, "Input too long");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->symbology != BARCODE_ISBNX) {
        /* ISBN has it's own checking routine */
        error_number = is_sane("0123456789+", source, src_len);
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in data");
            return error_number;
        }
    } else {
        error_number = is_sane("0123456789Xx", source, src_len);
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in input");
            return error_number;
        }
    }

    /* Add leading zeroes */
    ustrcpy(local_source, (unsigned char *) "");
    if (symbol->symbology == BARCODE_ISBNX) {







|






|





|







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750


    with_addon = FALSE;
    latch = FALSE;
    writer = 0;

    if (src_len > 19) {
        strcpy(symbol->errtxt, "Input too long (C6D)");
        return ZINT_ERROR_TOO_LONG;
    }
    if (symbol->symbology != BARCODE_ISBNX) {
        /* ISBN has it's own checking routine */
        error_number = is_sane("0123456789+", source, src_len);
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in data (C6E)");
            return error_number;
        }
    } else {
        error_number = is_sane("0123456789Xx", source, src_len);
        if (error_number == ZINT_ERROR_INVALID_DATA) {
            strcpy(symbol->errtxt, "Invalid characters in input (C6F)");
            return error_number;
        }
    }

    /* Add leading zeroes */
    ustrcpy(local_source, (unsigned char *) "");
    if (symbol->symbology == BARCODE_ISBNX) {
683
684
685
686
687
688
689

690
691
692
693
694
695
696

697
698

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788



789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
        } while (reader <= ustrlen(local_source));
    } else {
        strcpy((char*) first_part, (char*) local_source);
    }

    switch (symbol->symbology) {
        case BARCODE_EANX:

            switch (ustrlen(first_part)) {
                case 2: add_on(first_part, (char*) dest, 0);
                    ustrcpy(symbol->text, first_part);
                    break;
                case 5: add_on(first_part, (char*) dest, 0);
                    ustrcpy(symbol->text, first_part);
                    break;

                case 7: ean8(symbol, first_part, (char*) dest);
                    break;

                case 12: ean13(symbol, first_part, (char*) dest);
                    break;
                default: strcpy(symbol->errtxt, "Invalid length input");
                    return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_EANX_CC:
            switch (ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */
                case 7: set_module(symbol, symbol->rows, 1);
                    set_module(symbol, symbol->rows, 67);
                    set_module(symbol, symbol->rows + 1, 0);
                    set_module(symbol, symbol->rows + 1, 68);
                    set_module(symbol, symbol->rows + 2, 1);
                    set_module(symbol, symbol->rows + 1, 67);
                    symbol->row_height[symbol->rows] = 2;
                    symbol->row_height[symbol->rows + 1] = 2;
                    symbol->row_height[symbol->rows + 2] = 2;
                    symbol->rows += 3;
                    ean8(symbol, first_part, (char*) dest);
                    break;
                case 12:set_module(symbol, symbol->rows, 1);
                    set_module(symbol, symbol->rows, 95);
                    set_module(symbol, symbol->rows + 1, 0);
                    set_module(symbol, symbol->rows + 1, 96);
                    set_module(symbol, symbol->rows + 2, 1);
                    set_module(symbol, symbol->rows + 2, 95);
                    symbol->row_height[symbol->rows] = 2;
                    symbol->row_height[symbol->rows + 1] = 2;
                    symbol->row_height[symbol->rows + 2] = 2;
                    symbol->rows += 3;
                    ean13(symbol, first_part, (char*) dest);
                    break;
                default: strcpy(symbol->errtxt, "Invalid length EAN input");
                    return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCA:

            if (ustrlen(first_part) == 11) {
                upca(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "Input wrong length");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCA_CC:
            if (ustrlen(first_part) == 11) {
                set_module(symbol, symbol->rows, 1);
                set_module(symbol, symbol->rows, 95);
                set_module(symbol, symbol->rows + 1, 0);
                set_module(symbol, symbol->rows + 1, 96);
                set_module(symbol, symbol->rows + 2, 1);
                set_module(symbol, symbol->rows + 2, 95);
                symbol->row_height[symbol->rows] = 2;
                symbol->row_height[symbol->rows + 1] = 2;
                symbol->row_height[symbol->rows + 2] = 2;
                symbol->rows += 3;
                upca(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "UPCA input wrong length");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCE:

            if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) {
                upce(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "Input wrong length");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCE_CC:
            if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) {
                set_module(symbol, symbol->rows, 1);
                set_module(symbol, symbol->rows, 51);
                set_module(symbol, symbol->rows + 1, 0);
                set_module(symbol, symbol->rows + 1, 52);
                set_module(symbol, symbol->rows + 2, 1);
                set_module(symbol, symbol->rows + 2, 51);
                symbol->row_height[symbol->rows] = 2;
                symbol->row_height[symbol->rows + 1] = 2;
                symbol->row_height[symbol->rows + 2] = 2;
                symbol->rows += 3;
                upce(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "UPCE input wrong length");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_ISBNX:
            error_number = isbn(symbol, first_part, ustrlen(first_part), (char*) dest);



            if (error_number > 4) {
                return error_number;
            }
            break;
    }
    switch (ustrlen(second_part)) {
        case 0: break;
        case 2:
            add_on(second_part, (char*) dest, 1);
            strcat((char*) symbol->text, "+");
            strcat((char*) symbol->text, (char*) second_part);
            break;
        case 5:
            add_on(second_part, (char*) dest, 1);
            strcat((char*) symbol->text, "+");
            strcat((char*) symbol->text, (char*) second_part);
            break;
        default:
            strcpy(symbol->errtxt, "Invalid length input");
            return ZINT_ERROR_TOO_LONG;
    }

    expand(symbol, (char*) dest);

    switch (symbol->symbology) {
        case BARCODE_EANX_CC:







>







>
|

>
|

|















|











|

|




>
|
|

|















|

|




>
|
|

|















|

|





>
>
>
|
|
|
<
|













|







781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
        } while (reader <= ustrlen(local_source));
    } else {
        strcpy((char*) first_part, (char*) local_source);
    }

    switch (symbol->symbology) {
        case BARCODE_EANX:
        case BARCODE_EANX_CHK:
            switch (ustrlen(first_part)) {
                case 2: add_on(first_part, (char*) dest, 0);
                    ustrcpy(symbol->text, first_part);
                    break;
                case 5: add_on(first_part, (char*) dest, 0);
                    ustrcpy(symbol->text, first_part);
                    break;
                case 7:
                case 8: error_number = ean8(symbol, first_part, (char*) dest);
                    break;
                case 12: 
                case 13: error_number = ean13(symbol, first_part, (char*) dest);
                    break;
                default: strcpy(symbol->errtxt, "Invalid length input (C6G)");
                    return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_EANX_CC:
            switch (ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */
                case 7: set_module(symbol, symbol->rows, 1);
                    set_module(symbol, symbol->rows, 67);
                    set_module(symbol, symbol->rows + 1, 0);
                    set_module(symbol, symbol->rows + 1, 68);
                    set_module(symbol, symbol->rows + 2, 1);
                    set_module(symbol, symbol->rows + 1, 67);
                    symbol->row_height[symbol->rows] = 2;
                    symbol->row_height[symbol->rows + 1] = 2;
                    symbol->row_height[symbol->rows + 2] = 2;
                    symbol->rows += 3;
                    error_number = ean8(symbol, first_part, (char*) dest);
                    break;
                case 12:set_module(symbol, symbol->rows, 1);
                    set_module(symbol, symbol->rows, 95);
                    set_module(symbol, symbol->rows + 1, 0);
                    set_module(symbol, symbol->rows + 1, 96);
                    set_module(symbol, symbol->rows + 2, 1);
                    set_module(symbol, symbol->rows + 2, 95);
                    symbol->row_height[symbol->rows] = 2;
                    symbol->row_height[symbol->rows + 1] = 2;
                    symbol->row_height[symbol->rows + 2] = 2;
                    symbol->rows += 3;
                    error_number = ean13(symbol, first_part, (char*) dest);
                    break;
                default: strcpy(symbol->errtxt, "Invalid length EAN input (C6H)");
                    return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCA:
        case BARCODE_UPCA_CHK:
            if ((ustrlen(first_part) == 11) || (ustrlen(first_part) == 12)) {
                error_number = upca(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "Input wrong length (C6I)");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCA_CC:
            if (ustrlen(first_part) == 11) {
                set_module(symbol, symbol->rows, 1);
                set_module(symbol, symbol->rows, 95);
                set_module(symbol, symbol->rows + 1, 0);
                set_module(symbol, symbol->rows + 1, 96);
                set_module(symbol, symbol->rows + 2, 1);
                set_module(symbol, symbol->rows + 2, 95);
                symbol->row_height[symbol->rows] = 2;
                symbol->row_height[symbol->rows + 1] = 2;
                symbol->row_height[symbol->rows + 2] = 2;
                symbol->rows += 3;
                error_number = upca(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "UPCA input wrong length (C6J)");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCE:
        case BARCODE_UPCE_CHK:
            if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 8)) {
                error_number = upce(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "Input wrong length (C6K)");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_UPCE_CC:
            if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) {
                set_module(symbol, symbol->rows, 1);
                set_module(symbol, symbol->rows, 51);
                set_module(symbol, symbol->rows + 1, 0);
                set_module(symbol, symbol->rows + 1, 52);
                set_module(symbol, symbol->rows + 2, 1);
                set_module(symbol, symbol->rows + 2, 51);
                symbol->row_height[symbol->rows] = 2;
                symbol->row_height[symbol->rows + 1] = 2;
                symbol->row_height[symbol->rows + 2] = 2;
                symbol->rows += 3;
                error_number = upce(symbol, first_part, (char*) dest);
            } else {
                strcpy(symbol->errtxt, "UPCE input wrong length (C6L)");
                return ZINT_ERROR_TOO_LONG;
            }
            break;
        case BARCODE_ISBNX:
            error_number = isbn(symbol, first_part, ustrlen(first_part), (char*) dest);
            break;
    }
    
    if (error_number > 4) {
        return error_number;
    }

    
    switch (ustrlen(second_part)) {
        case 0: break;
        case 2:
            add_on(second_part, (char*) dest, 1);
            strcat((char*) symbol->text, "+");
            strcat((char*) symbol->text, (char*) second_part);
            break;
        case 5:
            add_on(second_part, (char*) dest, 1);
            strcat((char*) symbol->text, "+");
            strcat((char*) symbol->text, (char*) second_part);
            break;
        default:
            strcpy(symbol->errtxt, "Invalid length input (C6M)");
            return ZINT_ERROR_TOO_LONG;
    }

    expand(symbol, (char*) dest);

    switch (symbol->symbology) {
        case BARCODE_EANX_CC:
823
824
825
826
827
828
829
830
831
832
833
834
835
                }
            }
            unset_module(symbol, symbol->rows - 1, 0);
            symbol->width += 2;
            break;
    }


    if ((symbol->errtxt[0] == 'w') && (error_number == 0)) {
        error_number = 1; /* flag UPC-E warnings */
    }
    return error_number;
}







<
<
<
<
|

928
929
930
931
932
933
934




935
936
                }
            }
            unset_module(symbol, symbol->rows - 1, 0);
            symbol->width += 2;
            break;
    }





    return 0;
}
Changes to jni/zint/backend/zint.h.
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94


95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122

123

124
125
126
127
128
129
130
        char outfile[256];
        float scale;
        int option_1;
        int option_2;
        int option_3;
        int show_hrt;
        int input_mode;

        unsigned char text[128];
        int rows;
        int width;
        char primary[128];
        unsigned char encoded_data[178][143];
        int row_height[178]; /* Largest symbol is 177x177 QR Code */
        char errtxt[100];
        char *bitmap;
        int bitmap_width;
        int bitmap_height;


        struct zint_render *rendered;
    };


    /* Tbarcode 7 codes */
#define BARCODE_CODE11		1
#define BARCODE_C25MATRIX	2
#define BARCODE_C25INTER	3
#define BARCODE_C25IATA		4
#define BARCODE_C25LOGIC	6
#define BARCODE_C25IND		7
#define BARCODE_CODE39		8
#define BARCODE_EXCODE39	9
#define BARCODE_EANX		13

#define BARCODE_EAN128		16
#define BARCODE_CODABAR		18
#define BARCODE_CODE128		20
#define BARCODE_DPLEIT		21
#define BARCODE_DPIDENT		22
#define BARCODE_CODE16K		23
#define BARCODE_CODE49		24
#define BARCODE_CODE93		25
#define BARCODE_FLAT		28
#define BARCODE_RSS14		29
#define BARCODE_RSS_LTD		30
#define BARCODE_RSS_EXP		31
#define BARCODE_TELEPEN		32
#define BARCODE_UPCA		34

#define BARCODE_UPCE		37

#define BARCODE_POSTNET		40
#define BARCODE_MSI_PLESSEY	47
#define BARCODE_FIM		49
#define BARCODE_LOGMARS		50
#define BARCODE_PHARMA		51
#define BARCODE_PZN		52
#define BARCODE_PHARMA_TWO	53







>




|
|




>
>














>














>

>







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
        char outfile[256];
        float scale;
        int option_1;
        int option_2;
        int option_3;
        int show_hrt;
        int input_mode;
        int eci;
        unsigned char text[128];
        int rows;
        int width;
        char primary[128];
        unsigned char encoded_data[200][143];
        int row_height[200]; /* Largest symbol is 189 x 189 Han Xin */
        char errtxt[100];
        char *bitmap;
        int bitmap_width;
        int bitmap_height;
        unsigned int bitmap_byte_length;
        float dot_size;
        struct zint_render *rendered;
    };


    /* Tbarcode 7 codes */
#define BARCODE_CODE11		1
#define BARCODE_C25MATRIX	2
#define BARCODE_C25INTER	3
#define BARCODE_C25IATA		4
#define BARCODE_C25LOGIC	6
#define BARCODE_C25IND		7
#define BARCODE_CODE39		8
#define BARCODE_EXCODE39	9
#define BARCODE_EANX		13
#define BARCODE_EANX_CHK        14
#define BARCODE_EAN128		16
#define BARCODE_CODABAR		18
#define BARCODE_CODE128		20
#define BARCODE_DPLEIT		21
#define BARCODE_DPIDENT		22
#define BARCODE_CODE16K		23
#define BARCODE_CODE49		24
#define BARCODE_CODE93		25
#define BARCODE_FLAT		28
#define BARCODE_RSS14		29
#define BARCODE_RSS_LTD		30
#define BARCODE_RSS_EXP		31
#define BARCODE_TELEPEN		32
#define BARCODE_UPCA		34
#define BARCODE_UPCA_CHK        35
#define BARCODE_UPCE		37
#define BARCODE_UPCE_CHK        38
#define BARCODE_POSTNET		40
#define BARCODE_MSI_PLESSEY	47
#define BARCODE_FIM		49
#define BARCODE_LOGMARS		50
#define BARCODE_PHARMA		51
#define BARCODE_PZN		52
#define BARCODE_PHARMA_TWO	53
166
167
168
169
170
171
172




173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196



197

198
199
200
201
202
203

204
205
206

207

208
209
210
211
212
213
214







215
216
217
218
219
220
221
#define BARCODE_HIBC_39		99
#define BARCODE_HIBC_DM		102
#define BARCODE_HIBC_QR		104
#define BARCODE_HIBC_PDF	106
#define BARCODE_HIBC_MICPDF	108
#define BARCODE_HIBC_BLOCKF	110
#define BARCODE_HIBC_AZTEC	112





    /* Zint specific */
#define BARCODE_AZRUNE		128
#define BARCODE_CODE32		129
#define BARCODE_EANX_CC		130
#define BARCODE_EAN128_CC	131
#define BARCODE_RSS14_CC	132
#define BARCODE_RSS_LTD_CC	133
#define BARCODE_RSS_EXP_CC	134
#define BARCODE_UPCA_CC		135
#define BARCODE_UPCE_CC		136
#define BARCODE_RSS14STACK_CC	137
#define BARCODE_RSS14_OMNI_CC	138
#define BARCODE_RSS_EXPSTACK_CC	139
#define BARCODE_CHANNEL		140
#define BARCODE_CODEONE		141
#define BARCODE_GRIDMATRIX	142


#define BARCODE_NO_ASCII	1
#define BARCODE_BIND		2
#define BARCODE_BOX		4
#define BARCODE_STDOUT		8
#define READER_INIT		16
#define SMALL_TEXT		32





#define DATA_MODE	0
#define UNICODE_MODE	1
#define GS1_MODE	2
#define KANJI_MODE	3
#define SJIS_MODE	4


#define DM_SQUARE	100
#define DM_DMRE	101


#define ZINT_WARN_INVALID_OPTION	2

#define ZINT_ERROR_TOO_LONG		5
#define ZINT_ERROR_INVALID_DATA	6
#define ZINT_ERROR_INVALID_CHECK	7
#define ZINT_ERROR_INVALID_OPTION	8
#define ZINT_ERROR_ENCODING_PROBLEM	9
#define ZINT_ERROR_FILE_ACCESS	10
#define ZINT_ERROR_MEMORY		11








#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER)
#if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL)
#define ZINT_EXTERN __declspec(dllexport)
#elif defined(ZINT_DLL)
#define ZINT_EXTERN __declspec(dllimport)
#else







>
>
>
>


















>






>
>
>

>






>

|

>

>

|



|

>
>
>
>
>
>
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#define BARCODE_HIBC_39		99
#define BARCODE_HIBC_DM		102
#define BARCODE_HIBC_QR		104
#define BARCODE_HIBC_PDF	106
#define BARCODE_HIBC_MICPDF	108
#define BARCODE_HIBC_BLOCKF	110
#define BARCODE_HIBC_AZTEC	112
    
    /* Tbarcode 10 codes */
#define BARCODE_DOTCODE         115
#define BARCODE_HANXIN          116

    /* Zint specific */
#define BARCODE_AZRUNE		128
#define BARCODE_CODE32		129
#define BARCODE_EANX_CC		130
#define BARCODE_EAN128_CC	131
#define BARCODE_RSS14_CC	132
#define BARCODE_RSS_LTD_CC	133
#define BARCODE_RSS_EXP_CC	134
#define BARCODE_UPCA_CC		135
#define BARCODE_UPCE_CC		136
#define BARCODE_RSS14STACK_CC	137
#define BARCODE_RSS14_OMNI_CC	138
#define BARCODE_RSS_EXPSTACK_CC	139
#define BARCODE_CHANNEL		140
#define BARCODE_CODEONE		141
#define BARCODE_GRIDMATRIX	142

// Output options
#define BARCODE_NO_ASCII	1
#define BARCODE_BIND		2
#define BARCODE_BOX		4
#define BARCODE_STDOUT		8
#define READER_INIT		16
#define SMALL_TEXT		32
#define BOLD_TEXT               64
#define CMYK_COLOUR             128
#define BARCODE_DOTTY_MODE      256

// Input data types
#define DATA_MODE	0
#define UNICODE_MODE	1
#define GS1_MODE	2
#define KANJI_MODE	3
#define SJIS_MODE	4

// Data Matrix specific options
#define DM_SQUARE	100
#define DM_DMRE	        101

// Warning and error conditions
#define ZINT_WARN_INVALID_OPTION	2
#define ZINT_WARN_USES_ECI              3
#define ZINT_ERROR_TOO_LONG		5
#define ZINT_ERROR_INVALID_DATA	        6
#define ZINT_ERROR_INVALID_CHECK	7
#define ZINT_ERROR_INVALID_OPTION	8
#define ZINT_ERROR_ENCODING_PROBLEM	9
#define ZINT_ERROR_FILE_ACCESS	        10
#define ZINT_ERROR_MEMORY		11
    
// Raster file types
#define OUT_BUFFER          0
#define	OUT_PNG_FILE        100
#define	OUT_BMP_FILE        120
#define OUT_GIF_FILE        140
#define OUT_PCX_FILE        160

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER)
#if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL)
#define ZINT_EXTERN __declspec(dllexport)
#elif defined(ZINT_DLL)
#define ZINT_EXTERN __declspec(dllimport)
#else
Changes to jni/zint/backend_qt4/backend_qt4.pro.
49
50
51
52
53
54
55

56
57
58
59

60
61
62

63
64
65
66
67
68
69

70
71
72
73
74
75


76
77
78
79
80
81
82



83
84

85
86
87
88
89

90
91
92
93

94
95
96
97
98
99
100
           qrencode/qrinput.c \
           qrencode/qrspec.c \
           qrencode/rscode.c \
           qrencode/split.c 
}

HEADERS +=  ../backend/aztec.h \

            ../backend/code49.h \
            ../backend/common.h \
            ../backend/composite.h \
            ../backend/dmatrix.h \

            ../backend/font.h \
            ../backend/gridmtx.h \
            ../backend/gs1.h \

            ../backend/large.h \
            ../backend/maxicode.h \
            ../backend/maxipng.h \
            ../backend/pdf417.h \
            ../backend/reedsol.h \
            ../backend/rss.h \
            ../backend/sjis.h \

            ../backend/zint.h \
            qzint.h

SOURCES += ../backend/2of5.c \
           ../backend/auspost.c \
           ../backend/aztec.c \


           ../backend/code.c \
           ../backend/code128.c \
           ../backend/code16k.c \
           ../backend/code49.c \
           ../backend/common.c \
           ../backend/composite.c \
           ../backend/dmatrix.c \



           ../backend/gridmtx.c \
           ../backend/gs1.c \

           ../backend/imail.c \
           ../backend/large.c \
           ../backend/library.c \
           ../backend/maxicode.c \
           ../backend/medical.c \

           ../backend/pdf417.c \
           ../backend/plessey.c \
           ../backend/postal.c \
           ../backend/ps.c \

           ../backend/reedsol.c \
            ../backend/render.c \
           ../backend/rss.c \
           ../backend/svg.c \
           ../backend/telepen.c \
           ../backend/upcean.c \
           ../backend/qr.c \







>




>



>


|




>






>
>







>
>
>


>





>




>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
           qrencode/qrinput.c \
           qrencode/qrspec.c \
           qrencode/rscode.c \
           qrencode/split.c 
}

HEADERS +=  ../backend/aztec.h \
            ../backend/bmp.h \
            ../backend/code49.h \
            ../backend/common.h \
            ../backend/composite.h \
            ../backend/dmatrix.h \
            ../backend/eci.h \
            ../backend/font.h \
            ../backend/gridmtx.h \
            ../backend/gs1.h \
            ../backend/hanxin.h \
            ../backend/large.h \
            ../backend/maxicode.h \
            ../backend/pcx.h \
            ../backend/pdf417.h \
            ../backend/reedsol.h \
            ../backend/rss.h \
            ../backend/sjis.h \
            ../backend/stdint_msvc.h \
            ../backend/zint.h \
            qzint.h

SOURCES += ../backend/2of5.c \
           ../backend/auspost.c \
           ../backend/aztec.c \
           ../backend/bmp.c \
           ../backend/codablock.c \
           ../backend/code.c \
           ../backend/code128.c \
           ../backend/code16k.c \
           ../backend/code49.c \
           ../backend/common.c \
           ../backend/composite.c \
           ../backend/dmatrix.c \
           ../backend/dotcode.c \
           ../backend/eci.c \
           ../backend/gif.c \
           ../backend/gridmtx.c \
           ../backend/gs1.c \
           ../backend/hanxin.c \
           ../backend/imail.c \
           ../backend/large.c \
           ../backend/library.c \
           ../backend/maxicode.c \
           ../backend/medical.c \
           ../backend/pcx.c \
           ../backend/pdf417.c \
           ../backend/plessey.c \
           ../backend/postal.c \
           ../backend/ps.c \
           ../backend/raster.c \
           ../backend/reedsol.c \
            ../backend/render.c \
           ../backend/rss.c \
           ../backend/svg.c \
           ../backend/telepen.c \
           ../backend/upcean.c \
           ../backend/qr.c \
Changes to jni/zint/backend_qt4/backend_vc8.pro.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
            ../backend/dmatrix.h \
            ../backend/font.h \
            ../backend/gb2312.h \
            ../backend/gridmtx.h \
            ../backend/gs1.h \
            ../backend/large.h \
            ../backend/maxicode.h \
            ../backend/maxipng.h \
            ../backend/ms_stdint.h \
            ../backend/pdf417.h \
            ../backend/qr.h \
            ../backend/reedsol.h \
            ../backend/rss.h \
            ../backend/sjis.h \
            ../backend/zint.h \







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
            ../backend/dmatrix.h \
            ../backend/font.h \
            ../backend/gb2312.h \
            ../backend/gridmtx.h \
            ../backend/gs1.h \
            ../backend/large.h \
            ../backend/maxicode.h \
            ../backend/maxihex.h \
            ../backend/ms_stdint.h \
            ../backend/pdf417.h \
            ../backend/qr.h \
            ../backend/reedsol.h \
            ../backend/rss.h \
            ../backend/sjis.h \
            ../backend/zint.h \
Changes to jni/zint/backend_qt4/qzint.cpp.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90

91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126


127
128
129
130









131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154



155
156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180

181
182
183
184


185

186
187
188
189

190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227


228

229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290



291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359





360


361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429




430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512


513

514






515





516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

540
541
542



543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

567


568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584

585


586

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644


645

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660

661


662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
/***************************************************************************
 *   Copyright (C) 2008 by BogDan Vatra                                    *
 *   bogdan@licentia.eu                                                    *

 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "qzint.h"
#include <stdio.h>

namespace Zint
{

static const qreal maxi_diagonal=11;
static const qreal maxi_width=1.73205807568877*maxi_diagonal/2;
static const char* fontstyle="Arial";
static const int fontPixelSizeSmall=6;
static const int fontPixelSizeLarge=8;

QZint::QZint()
{
	m_symbol=BARCODE_CODE128;
	m_height=50;
	m_border=NO_BORDER;
	m_borderWidth=1;
	m_securityLevel=-1;
	m_pdf417CodeWords=928;
	m_fgColor=Qt::black;
	m_bgColor=Qt::white;
	m_zintSymbol=0;
	m_error=0;
	m_input_mode = UNICODE_MODE;
	m_scale = 1.0;
	m_option_3 = 0;
	m_hidetext = FALSE;

}

QZint::~QZint()
{
	if (m_zintSymbol)
		ZBarcode_Delete(m_zintSymbol);
}

void QZint::encode()
{
	if (m_zintSymbol)
		ZBarcode_Delete(m_zintSymbol);

	m_lastError.clear();
	m_zintSymbol = ZBarcode_Create();
	m_zintSymbol->output_options=m_border;
	m_zintSymbol->symbology=m_symbol;
	m_zintSymbol->height=m_height;
	m_zintSymbol->whitespace_width=m_whitespace;
	m_zintSymbol->border_width=m_borderWidth;
	m_zintSymbol->option_1=m_securityLevel;
	m_zintSymbol->input_mode = m_input_mode;
	m_zintSymbol->option_2=m_width;

	if(m_hidetext) {
		m_zintSymbol->show_hrt = 0;
	} else {
		m_zintSymbol->show_hrt = 1;
	}
	if(m_symbol == BARCODE_PDF417) {
		m_zintSymbol->option_3=m_pdf417CodeWords;
	} else {
		m_zintSymbol->option_3 = m_option_3;
	}
	QByteArray bstr=m_text.toUtf8();
	QByteArray pstr=m_primaryMessage.left(99).toAscii();
	strcpy(m_zintSymbol->primary,pstr.data());
	int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length());
	if (error > ZINT_WARN_INVALID_OPTION)
		m_lastError=m_zintSymbol->errtxt;

	if (m_zintSymbol->symbology == BARCODE_MAXICODE)
		m_zintSymbol->height = 33;
	
	switch(m_zintSymbol->output_options) {
		case 0: m_border = NO_BORDER; break;

		case 2: m_border = BIND; break;

		case 4: m_border = BOX; break;

	}
	m_borderWidth = (BorderType)m_zintSymbol->border_width;
	m_whitespace = m_zintSymbol->whitespace_width;
}

int  QZint::symbol()
{
	return m_symbol;
}
void QZint::setSymbol(int symbol)
{
	m_symbol=symbol;
}

void QZint::setInputMode(int input_mode)
{

	m_input_mode = input_mode;
}

QString QZint::text()
{
	return m_text;
}
void QZint::setText(const QString & text)
{

	m_text=text;
}

QString QZint::primaryMessage()
{
	return m_primaryMessage;
}
void QZint::setPrimaryMessage(const QString & primaryMessage)
{
	m_primaryMessage=primaryMessage;


}

int QZint::height()
{









	encode();
	return (m_zintSymbol->height+(m_border!=NO_BORDER)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1);
}

void QZint::setHeight(int height)
{
	m_height=height;
}

void QZint::setWidth(int width)
{
	m_width=width;
}

void QZint::setOption3(int option)
{
	m_option_3 = option;
}

int QZint::width()
{
	encode();
	return (m_zintSymbol->width+(m_border==BOX)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1);
}




float QZint::scale()
{

	return m_scale;
}

void QZint::setScale(float scale)
{
	m_scale = scale;
}

QColor QZint::fgColor()
{
	return m_fgColor;
}
void QZint::setFgColor(const QColor & fgColor)
{

	m_fgColor=fgColor;
}

QColor QZint::bgColor()
{
	return m_bgColor;
}
void QZint::setBgColor(const QColor & bgColor)
{

	m_bgColor=bgColor;
}

QZint::BorderType QZint::borderType()


{

	return m_border;
}
void QZint::setBorderType(BorderType border)
{

	m_border=border;
}

int QZint::borderWidth()
{
	return m_borderWidth;
}
void QZint::setBorderWidth(int boderWidth)
{

	if (boderWidth<1 || boderWidth>16)
		boderWidth=1;
	m_borderWidth=boderWidth;
}

void QZint::setWhitespace(int whitespace)
{
	m_whitespace = whitespace;
}

int QZint::pdf417CodeWords()
{
	return m_pdf417CodeWords;
}
void QZint::setPdf417CodeWords(int pdf417CodeWords)
{

	m_pdf417CodeWords=pdf417CodeWords;
}

int QZint::securityLevel()
{
	return m_securityLevel;
}
void QZint::setSecurityLevel(int securityLevel)
{
	m_securityLevel=securityLevel;
}

QString QZint::error_message()


{

	return m_lastError;
}

int QZint::mode()
{
	return m_securityLevel;
}
void QZint::setMode(int securityLevel)
{

	m_securityLevel=securityLevel;
}

void QZint::setHideText(bool hide)
{
	m_hidetext = hide;
}

bool QZint::save_to_file(QString filename)
{
	if (m_zintSymbol)
		ZBarcode_Delete(m_zintSymbol);
	
	QString fg_colour_hash = m_fgColor.name();
	QString bg_colour_hash = m_bgColor.name();

	m_lastError.clear();
	m_zintSymbol = ZBarcode_Create();
	m_zintSymbol->output_options=m_border;
	m_zintSymbol->symbology=m_symbol;
	m_zintSymbol->height=m_height;
	m_zintSymbol->whitespace_width=m_whitespace;
	m_zintSymbol->border_width=m_borderWidth;
	m_zintSymbol->option_1=m_securityLevel;
	m_zintSymbol->input_mode = m_input_mode;
	m_zintSymbol->option_2=m_width;

	if(m_hidetext) {
		m_zintSymbol->show_hrt = 0;
	} else {
		m_zintSymbol->show_hrt = 1;
	}
	if(m_symbol == BARCODE_PDF417) {
		m_zintSymbol->option_3=m_pdf417CodeWords;
	} else {
		m_zintSymbol->option_3 = m_option_3;
	}
	m_zintSymbol->scale=m_scale;
	QByteArray bstr=m_text.toUtf8();
	QByteArray pstr=m_primaryMessage.left(99).toAscii();
	QByteArray fstr=filename.left(255).toAscii();
	strcpy(m_zintSymbol->primary,pstr.data());
	strcpy(m_zintSymbol->outfile,fstr.data());
	QByteArray fgcol=fg_colour_hash.right(6).toAscii();
	QByteArray bgcol=bg_colour_hash.right(6).toAscii();
	strcpy(m_zintSymbol->fgcolour,fgcol.data());
	strcpy(m_zintSymbol->bgcolour,bgcol.data());
	int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length());
	if (error > ZINT_WARN_INVALID_OPTION)
		m_lastError=m_zintSymbol->errtxt;
	error = ZBarcode_Print(m_zintSymbol, 0);
	if (error > ZINT_WARN_INVALID_OPTION)
		m_lastError=m_zintSymbol->errtxt;
	if(error == 0) { return true; } else { return false; }



}

int QZint::module_set(int y_coord, int x_coord)
{

	int x_char, x_sub, result;
	
	x_char = x_coord / 7;
	x_sub = x_coord % 7;
	result = 0;
	
	switch(x_sub) {
		case 0: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x01) != 0) { result = 1; } break;
		case 1: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x02) != 0) { result = 1; } break;
		case 2: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x04) != 0) { result = 1; } break;
		case 3: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x08) != 0) { result = 1; } break;
		case 4: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x10) != 0) { result = 1; } break;
		case 5: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x20) != 0) { result = 1; } break;
		case 6: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x40) != 0) { result = 1; } break;
	}
	
	return result;
}

void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode)
{
	encode();
	bool textdone;
	int comp_offset = 0, xoffset = m_whitespace, j, main_width = 0, addon_text_height = 0;
	int yoffset = 0;
	QString caption = QString::fromUtf8((const char *)m_zintSymbol->text, -1);
	QFont fontSmall(fontstyle);
	fontSmall.setPixelSize(fontPixelSizeSmall);
	QFont fontLarge(fontstyle);
	fontLarge.setPixelSize(fontPixelSizeLarge);

	if (m_lastError.length())
	{
		painter.setFont(fontLarge);
		painter.drawText(paintRect,Qt::AlignCenter,m_lastError);
		return;
	}

	painter.save();
	painter.setClipRect(paintRect,Qt::IntersectClip);
	qreal xtr=paintRect.x();
	qreal ytr=paintRect.y();

	int zrow_height=m_zintSymbol->height;
	int zrows=0;
	for (int i=0;i<m_zintSymbol->rows;i++)
	{
		zrow_height-=m_zintSymbol->row_height[i];
		if (!m_zintSymbol->row_height[i])
			zrows++;
	}
	if (zrows)
	{
		zrow_height/=zrows;
		for (int i=0;i<m_zintSymbol->rows;i++)
			if (!m_zintSymbol->row_height[i])
				m_zintSymbol->row_height[i]=zrow_height;
	}
	else
		m_zintSymbol->height-=zrow_height;


	qreal gwidth=m_zintSymbol->width;
	qreal gheight=m_zintSymbol->height;
	if (m_zintSymbol->symbology == BARCODE_MAXICODE)





	{


		gheight*=(maxi_width);
		gwidth*=(maxi_width+1);
	}

	qreal xsf=1;
	qreal ysf=1;
	qreal textoffset = 0;

	gwidth+=((m_border==BOX)?m_borderWidth*2:0);
	gheight+=((m_border!=NO_BORDER)?m_borderWidth*2:0);
	if(QString((const char*)m_zintSymbol->text).isEmpty() == false) {
		textoffset = 9;
		gheight += textoffset;
	} else {
		textoffset = 0;
	}
	gwidth+=m_zintSymbol->whitespace_width*2;
	switch(mode)
	{
		case IgnoreAspectRatio:
				xsf=(qreal)paintRect.width()/gwidth;
				ysf=(qreal)paintRect.height()/gheight;
			break;

		case KeepAspectRatio:
			if (paintRect.width()/gwidth<paintRect.height()/gheight)
			{
				ysf=xsf=(qreal)paintRect.width()/gwidth;
				ytr+=(qreal)(paintRect.height()-gheight*ysf)/2;
			}
			else
			{
				ysf=xsf=(qreal)paintRect.height()/gheight;
				xtr+=(qreal)(paintRect.width()-gwidth*xsf)/2;
			}
			break;

		case CenterBarCode:
				xtr+=((qreal)paintRect.width()-gwidth*xsf)/2;
				ytr+=((qreal)paintRect.height()-gheight*ysf)/2;
			break;

	}

	painter.setBackground(QBrush(m_bgColor));
	painter.fillRect(paintRect,QBrush(m_bgColor));
	painter.translate(xtr,ytr);
	painter.scale(xsf,ysf);

	QPen p;
	p.setColor(m_fgColor);
	p.setWidth(m_borderWidth);
	painter.setPen(p);

	QPainterPath pt;
	if(m_zintSymbol->symbology != BARCODE_MAXICODE) {
		/* Draw boundary bars or boxes around the symbol */
		switch(m_border)
		{
			case BOX:
				painter.fillRect(0,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor));
				painter.fillRect(m_zintSymbol->width + xoffset + xoffset + m_borderWidth,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor));
				painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth,m_borderWidth,QBrush(m_fgColor));
				painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth,QBrush(m_fgColor));
				painter.translate(m_borderWidth+m_zintSymbol->whitespace_width,m_borderWidth);
				yoffset = m_borderWidth;
				break;
			case BIND:

				painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset,m_borderWidth,QBrush(m_fgColor));
				painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset, m_borderWidth,QBrush(m_fgColor));




				painter.translate(m_zintSymbol->whitespace_width,m_borderWidth);
				yoffset = m_borderWidth;
				break;
	
			default:
				painter.translate(m_zintSymbol->whitespace_width,0);
				break;;

		}
	}

	while(!(module_set(m_zintSymbol->rows - 1, comp_offset))) {
		comp_offset++;
	}
	xoffset = comp_offset;
	
	/* Set up some values for displaying EAN and UPC symbols correctly */
	main_width = m_zintSymbol->width;
	if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC))
		|| (m_zintSymbol->symbology == BARCODE_ISBNX)) {
		switch(caption.size()) {
			case 13: /* EAN 13 */
			case 16:
			case 19:
				if(m_zintSymbol->whitespace_width == 0) {
					m_zintSymbol->whitespace_width = 10;
				}
				main_width = 96 + comp_offset;
				break;
			default:
				main_width = 68 + comp_offset;
				break;
		}
	}
	
	if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
		if(m_zintSymbol->whitespace_width == 0) {
			m_zintSymbol->whitespace_width = 10;
		}
		main_width = 96 + comp_offset;
	}
	
	if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
		if(m_zintSymbol->whitespace_width == 0) {
			m_zintSymbol->whitespace_width = 10;
		}
		main_width = 51 + comp_offset;
	}
	
	p.setWidth(1);
	painter.setPen(p);

	if (m_zintSymbol->symbology == BARCODE_MAXICODE)
	{
		/* Draw Maxicode with hexagons */
		painter.save();
		painter.setRenderHint(QPainter::Antialiasing);
		for (int r=0;r<m_zintSymbol->rows;r++)
		{
			for (int c=0;c<m_zintSymbol->width;c++)
			{
				if (module_set(r, c))
				{
					qreal col=(qreal)c*(maxi_width+1)+(r%2)*((maxi_width+1)/2);
					qreal row=(qreal)r*(maxi_width+1)*0.868;
					QPainterPath pt;
					pt.moveTo(col+maxi_width/2, 	row);
					pt.lineTo(col+maxi_width, 	row+maxi_diagonal/4);
					pt.lineTo(col+maxi_width, 	row+(maxi_diagonal-maxi_diagonal/4));
					pt.lineTo(col+maxi_width/2, 	row+maxi_diagonal);
					pt.lineTo(col, 			row+(maxi_diagonal-maxi_diagonal/4));
					pt.lineTo(col, 			row+maxi_diagonal/4);
					pt.lineTo(col+maxi_width/2, 	row);
					painter.fillPath(pt,QBrush(m_fgColor));
				}
			}
		}
		p.setWidth(maxi_width);
		painter.setPen(p);
		const qreal w=maxi_width+1;
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w,w);
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*1.5,w+w*1.5);
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*3,w+w*3);
		painter.restore();


	}

	else






	{





		/* Draw all other symbols with rectangles */
		int y=0;
		for (int row=0;row<m_zintSymbol->rows;row++)
		{
			for (int i=0;i<m_zintSymbol->width;i++) {
				if (module_set(row, i))
				{
					int ed = module_set(row, i);
					int linewidth=0;
					for (int j=i;j<m_zintSymbol->width;j++,linewidth++)
						if (ed != module_set(row, j))
							break;
					QColor color;
					color=m_fgColor;
					
					if(!((i > main_width) && (row == m_zintSymbol->rows - 1)))  {
						painter.fillRect(i,y,linewidth,m_zintSymbol->row_height[row],QBrush(color));
					} else {
						painter.fillRect(i,y + 8,linewidth,m_zintSymbol->row_height[row] - 3,QBrush(color));
						addon_text_height = y;
					}
				}
			}
			/* Add row binding */

			if(((m_zintSymbol->symbology == BARCODE_CODE16K) || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) {
				painter.fillRect(0,y - 1,m_zintSymbol->width,2,QBrush(m_fgColor));
			}



			y+=m_zintSymbol->row_height[row];
		}
	}

	textdone = false;
	
	if(m_hidetext == false) {
		painter.setFont(fontSmall);
		if(((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) ||
			(m_zintSymbol->symbology == BARCODE_ISBNX)) {
			/* Add bridge and format text for EAN */
			switch(caption.size()) {
				case 8:
				case 11:
				case 14:
					painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(32 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(34 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(64 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(66 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.setFont(fontLarge);
					painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(0,4));
					painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(4,4));

					if(caption.size() == 11) { /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); };


					if(caption.size() == 14) { /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); };

					painter.setFont(fontSmall);
					textdone = true;
					break;
				case 13:
				case 16:
				case 19:
					painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(92 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(94 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.setFont(fontLarge);
					painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9,Qt::AlignCenter, caption.mid(0,1));
					painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6));
					painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(7,6));

					if(caption.size() == 16) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(14,2)); };


					if(caption.size() == 19) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(14,5)); };

					painter.setFont(fontSmall);
					textdone = true;
					break;
			}
			if(textdone == false) {
				painter.setFont(fontLarge);
				painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9,Qt::AlignCenter, caption);
				painter.setFont(fontSmall);
				textdone = true;
			}
		}
		
		if((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
			/* Add bridge and format text for UPC-A */
			int block_width;
			bool latch = true;
			
			j = 0 + comp_offset;
			do {
				block_width = 0;
				do {
					block_width++;
				} while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
				if(latch == true) {
					/* a bar */
					painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor));
					latch = false;
				} else {
					/* a space */
					latch = true;
				}
				j += block_width;
			} while (j < 11 + comp_offset);
			painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			latch = true;
			j = 85 + comp_offset;
			do {
				block_width = 0;
				do {
					block_width++;
				} while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
				if(latch == true) {
					/* a bar */
					painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor));
					latch = false;
				} else {
					/* a space */
					latch = true;
				}
				j += block_width;
			} while (j < 96 + comp_offset);
			painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1));
			painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(11,1));
			painter.setFont(fontLarge);
			painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(1,5));
			painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(6,5));

			if(caption.size() == 15) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(13,2)); };


			if(caption.size() == 18) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(13,5)); };

			painter.setFont(fontSmall);
			textdone = true;
		}
		
		if((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
			/* Add bridge and format text for UPC-E */
			painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(50 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1));
			painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(7,1));
			painter.setFont(fontLarge);
			painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6));

			if(caption.size() == 11) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); };


			if(caption.size() == 14) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); };

			painter.setFont(fontSmall);
			textdone = true;
		}
	} /* if (m_hidetext == false) */
	
	if((m_hidetext == false) && (textdone == false)) {
		/* Add text to any other symbol */
		painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption);
	}
	painter.restore();
}

const QString & QZint::lastError()
{
	return m_lastError;
}

bool QZint::hasErrors()
{
	return m_lastError.length();
}

}




>
















|
|
<
|
|
|
|
|

|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|

|
<
|
|
|

|
<
|
|

|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
>
|
>
|
>
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
>
|
|

|
<
|
|
<
|
>
|
|

|
<
|
|
<
|
<
>
>
|
<
<
|
>
>
>
>
>
>
>
>
>
|
|
|

|
<
|
|

|
<
|
|

|
<
|
|
<
<
<
<
<
|
>
>
>
|
<
|
>
|
|

|
<
|
|
|
|
<
|
|
<
|
>
|
|

|
<
|
|
<
|
>
|
|

|
>
>
|
>
|
|
<
|
>
|
|

|
<
|
|
<
|
>
|
|
|
|

|
<
|
|

|
<
|
|
<
|
>
|
|

|
<
<
<
<
<
|
|

|
>
>
|
>
|
|

|
<
|
|
<
|
>
|
|

|
<
|
|

|
<
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
|
|
<
|
>
|
|
|
|
|
|
<
|
|
<
<
<
<
<
|
|
|
|

|
<
|
|
|
|
|
|
|
|
|

|
<
|
|
|
|

|
|
|
|

|
|
|
<
|
|
|
|
|
<
|
|
|
|
<
|
|


|
|
|
>
>
>
>
>
|
>
>
|
<
|

|
|
|

|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
<
|
|
<
|
<
|
|
|
|

|
|
|
|
>
|
<
|
|
|
|

|
|
|
|

|
|
|
|
<
|
|
|
|
|
|
|
|
|
>
|
|
>
>
>
>
|
|
|
|
|
|
|
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
<
|
|
|
|
<
|
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
>
>
>
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|

|
<
|
|

|
<
|
|


<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97











98
99
100
101
102
103

104
105

106
107
108
109
110
111

112
113

114

115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136

137
138
139
140

141
142





143
144
145
146
147

148
149
150
151
152
153

154
155
156
157

158
159

160
161
162
163
164
165

166
167

168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185

186
187

188
189
190
191
192
193
194
195

196
197
198
199

200
201

202
203
204
205
206
207





208
209
210
211
212
213
214
215
216
217
218
219

220
221

222
223
224
225
226
227

228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288

289
290





291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320

321
322
323
324
325

326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368

369
370

371

372
373
374
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465

466
467
468
469

470

471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690
691

692
693
694
695

/***************************************************************************
 *   Copyright (C) 2008 by BogDan Vatra                                    *
 *   bogdan@licentia.eu                                                    *
 *   Copyright (C) 2010-2016 Robin Stuart                                  *
 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "qzint.h"
#include <stdio.h>

namespace Zint {


    static const qreal maxi_diagonal = 11;
    static const qreal maxi_width = 1.73205807568877 * maxi_diagonal / 2;
    static const char* fontstyle = "Arial";
    static const int fontPixelSizeSmall = 6;
    static const int fontPixelSizeLarge = 8;

    QZint::QZint() {

        m_symbol = BARCODE_CODE128;
        m_height = 50;
        m_border = NO_BORDER;
        m_borderWidth = 1;
        m_securityLevel = -1;
        m_pdf417CodeWords = 928;
        m_fgColor = Qt::black;
        m_bgColor = Qt::white;
        m_zintSymbol = 0;
        m_error = 0;
        m_input_mode = UNICODE_MODE;
        m_scale = 1.0;
        m_option_3 = 0;
        m_hidetext = FALSE;
        m_dot_size = 4.0 / 5.0;
    }

    QZint::~QZint() {

        if (m_zintSymbol)
            ZBarcode_Delete(m_zintSymbol);
    }

    void QZint::encode() {

        if (m_zintSymbol)
            ZBarcode_Delete(m_zintSymbol);

        m_lastError.clear();
        m_zintSymbol = ZBarcode_Create();
        m_zintSymbol->output_options = m_border;
        m_zintSymbol->symbology = m_symbol;
        m_zintSymbol->height = m_height;
        m_zintSymbol->whitespace_width = m_whitespace;
        m_zintSymbol->border_width = m_borderWidth;
        m_zintSymbol->option_1 = m_securityLevel;
        m_zintSymbol->input_mode = m_input_mode;
        m_zintSymbol->option_2 = m_width;
        m_zintSymbol->dot_size = m_dot_size;
        if (m_hidetext) {
            m_zintSymbol->show_hrt = 0;
        } else {
            m_zintSymbol->show_hrt = 1;
        }
        if (m_symbol == BARCODE_PDF417) {
            m_zintSymbol->option_3 = m_pdf417CodeWords;
        } else {
            m_zintSymbol->option_3 = m_option_3;
        }
        QByteArray bstr = m_text.toUtf8();
        QByteArray pstr = m_primaryMessage.left(99).toAscii();
        strcpy(m_zintSymbol->primary, pstr.data());
        int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*) bstr.data(), bstr.length());
        if (error > ZINT_WARN_INVALID_OPTION)
            m_lastError = m_zintSymbol->errtxt;

        if (m_zintSymbol->symbology == BARCODE_MAXICODE)
            m_zintSymbol->height = 33;

        switch (m_zintSymbol->output_options) {
            case 0: m_border = NO_BORDER;
                break;
            case 2: m_border = BIND;
                break;
            case 4: m_border = BOX;
                break;
        }
        m_borderWidth = (BorderType) m_zintSymbol->border_width;
        m_whitespace = m_zintSymbol->whitespace_width;
    }












    int QZint::symbol() {
        return m_symbol;
    }

    void QZint::setSymbol(int symbol) {

        m_symbol = symbol;
    }


    void QZint::setInputMode(int input_mode) {
        m_input_mode = input_mode;
    }

    QString QZint::text() {

        return m_text;
    }



    void QZint::setText(const QString & text) {
        m_text = text;
    }



    QString QZint::primaryMessage() {
        return m_primaryMessage;
    }

    void QZint::setPrimaryMessage(const QString & primaryMessage) {
        m_primaryMessage = primaryMessage;
    }

    int QZint::height() {
        encode();
        return (m_zintSymbol->height + (m_border != NO_BORDER) ? m_borderWidth * 2 : 0)*(m_zintSymbol->symbology == BARCODE_MAXICODE ? (maxi_width + 1) : 1);
    }

    void QZint::setHeight(int height) {

        m_height = height;
    }

    void QZint::setWidth(int width) {

        m_width = width;
    }

    void QZint::setOption3(int option) {

        m_option_3 = option;
    }






    int QZint::width() {
        encode();
        return (m_zintSymbol->width + (m_border == BOX) ? m_borderWidth * 2 : 0)*(m_zintSymbol->symbology == BARCODE_MAXICODE ? (maxi_width + 1) : 1);
    }


    float QZint::scale() {
        return m_scale;
    }

    void QZint::setScale(float scale) {

        m_scale = scale;
    }
    
    void QZint::setDotSize(float dot_size) {

        m_dot_size = dot_size;
    }


    QColor QZint::fgColor() {
        return m_fgColor;
    }

    void QZint::setFgColor(const QColor & fgColor) {

        m_fgColor = fgColor;
    }


    QColor QZint::bgColor() {
        return m_bgColor;
    }

    void QZint::setBgColor(const QColor & bgColor) {
        m_bgColor = bgColor;
    }

    QZint::BorderType QZint::borderType() {
        return m_border;
    }


    void QZint::setBorderType(BorderType border) {
        m_border = border;
    }

    int QZint::borderWidth() {

        return m_borderWidth;
    }


    void QZint::setBorderWidth(int boderWidth) {
        if (boderWidth < 1 || boderWidth > 16)
            boderWidth = 1;
        m_borderWidth = boderWidth;
    }

    void QZint::setWhitespace(int whitespace) {

        m_whitespace = whitespace;
    }

    int QZint::pdf417CodeWords() {

        return m_pdf417CodeWords;
    }


    void QZint::setPdf417CodeWords(int pdf417CodeWords) {
        m_pdf417CodeWords = pdf417CodeWords;
    }

    int QZint::securityLevel() {





        return m_securityLevel;
    }

    void QZint::setSecurityLevel(int securityLevel) {
        m_securityLevel = securityLevel;
    }

    QString QZint::error_message() {
        return m_lastError;
    }

    int QZint::mode() {

        return m_securityLevel;
    }


    void QZint::setMode(int securityLevel) {
        m_securityLevel = securityLevel;
    }

    void QZint::setHideText(bool hide) {

        m_hidetext = hide;
    }

    bool QZint::save_to_file(QString filename) {

        if (m_zintSymbol)
            ZBarcode_Delete(m_zintSymbol);

        QString fg_colour_hash = m_fgColor.name();
        QString bg_colour_hash = m_bgColor.name();

        m_lastError.clear();
        m_zintSymbol = ZBarcode_Create();
        m_zintSymbol->output_options = m_border;
        m_zintSymbol->symbology = m_symbol;
        m_zintSymbol->height = m_height;
        m_zintSymbol->whitespace_width = m_whitespace;
        m_zintSymbol->border_width = m_borderWidth;
        m_zintSymbol->option_1 = m_securityLevel;
        m_zintSymbol->input_mode = m_input_mode;
        m_zintSymbol->option_2 = m_width;
        m_zintSymbol->dot_size = m_dot_size;
        if (m_hidetext) {
            m_zintSymbol->show_hrt = 0;
        } else {
            m_zintSymbol->show_hrt = 1;
        }
        if (m_symbol == BARCODE_PDF417) {
            m_zintSymbol->option_3 = m_pdf417CodeWords;
        } else {
            m_zintSymbol->option_3 = m_option_3;
        }
        m_zintSymbol->scale = m_scale;
        QByteArray bstr = m_text.toUtf8();
        QByteArray pstr = m_primaryMessage.left(99).toAscii();
        QByteArray fstr = filename.left(255).toAscii();
        strcpy(m_zintSymbol->primary, pstr.data());
        strcpy(m_zintSymbol->outfile, fstr.data());
        QByteArray fgcol = fg_colour_hash.right(6).toAscii();
        QByteArray bgcol = bg_colour_hash.right(6).toAscii();
        strcpy(m_zintSymbol->fgcolour, fgcol.data());
        strcpy(m_zintSymbol->bgcolour, bgcol.data());
        int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*) bstr.data(), bstr.length());
        if (error > ZINT_WARN_INVALID_OPTION)
            m_lastError = m_zintSymbol->errtxt;
        error = ZBarcode_Print(m_zintSymbol, 0);
        if (error > ZINT_WARN_INVALID_OPTION)
            m_lastError = m_zintSymbol->errtxt;
        if (error == 0) {
            return true;
        } else {
            return false;
        }
    }


    int QZint::module_set(int y_coord, int x_coord) {
        int x_char, x_sub, result;

        x_char = x_coord / 7;
        x_sub = x_coord % 7;
        result = 0;


        if (m_zintSymbol->encoded_data[y_coord][x_char] & (0x01 << x_sub)) {
            result = 1;





        }

        return result;
    }

    void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode) {

        encode();
        bool textdone;
        int comp_offset = 0, xoffset = m_whitespace, j, main_width = 0, addon_text_height = 0;
        int yoffset = 0;
        QString caption = QString::fromUtf8((const char *) m_zintSymbol->text, -1);
        QFont fontSmall(fontstyle);
        fontSmall.setPixelSize(fontPixelSizeSmall);
        QFont fontLarge(fontstyle);
        fontLarge.setPixelSize(fontPixelSizeLarge);

        if (m_lastError.length()) {

            painter.setFont(fontLarge);
            painter.drawText(paintRect, Qt::AlignCenter, m_lastError);
            return;
        }

        painter.save();
        painter.setClipRect(paintRect, Qt::IntersectClip);
        qreal xtr = paintRect.x();
        qreal ytr = paintRect.y();

        int zrow_height = m_zintSymbol->height;
        int zrows = 0;
        for (int i = 0; i < m_zintSymbol->rows; i++) {

            zrow_height -= m_zintSymbol->row_height[i];
            if (!m_zintSymbol->row_height[i])
                zrows++;
        }
        if (zrows) {

            zrow_height /= zrows;
            for (int i = 0; i < m_zintSymbol->rows; i++)
                if (!m_zintSymbol->row_height[i])
                    m_zintSymbol->row_height[i] = zrow_height;

        } else
            m_zintSymbol->height -= zrow_height;


        qreal gwidth = m_zintSymbol->width;
        qreal gheight = m_zintSymbol->height;
        if (m_zintSymbol->symbology == BARCODE_MAXICODE) {
//            gheight *= (maxi_width);
//            gwidth *= (maxi_width + 1);
            gwidth *= 2.0;
            gheight *= 2.0;
        }

        if (m_zintSymbol->output_options & BARCODE_DOTTY_MODE) {
            gwidth += 2.0;
            gheight += 2.0;

        }

        qreal xsf = 1;
        qreal ysf = 1;
        qreal textoffset = 0;

        gwidth += ((m_border == BOX) ? m_borderWidth * 2 : 0);
        gheight += ((m_border != NO_BORDER) ? m_borderWidth * 2 : 0);
        if (QString((const char*) m_zintSymbol->text).isEmpty() == false) {
            textoffset = 9;
            gheight += textoffset;
        } else {
            textoffset = 0;
        }
        gwidth += m_zintSymbol->whitespace_width * 2;
//        switch (mode) {

//            case IgnoreAspectRatio:
//                xsf = (qreal) paintRect.width() / gwidth;
//                ysf = (qreal) paintRect.height() / gheight;
//                break;
//
//            case KeepAspectRatio:
                if (paintRect.width() / gwidth < paintRect.height() / gheight) {

                    ysf = xsf = (qreal) paintRect.width() / gwidth;
                    ytr += (qreal) (paintRect.height() - gheight * ysf) / 2;

                } else {

                    ysf = xsf = (qreal) paintRect.height() / gheight;
                    xtr += (qreal) (paintRect.width() - gwidth * xsf) / 2;
                }
//                break;

//            case CenterBarCode:
//                xtr += ((qreal) paintRect.width() - gwidth * xsf) / 2;
//                ytr += ((qreal) paintRect.height() - gheight * ysf) / 2;
//                break;
//        }


        painter.setBackground(QBrush(m_bgColor));
        painter.fillRect(paintRect, QBrush(m_bgColor));
        painter.translate(xtr, ytr);
        painter.scale(xsf, ysf);

        QPen p;
        p.setColor(m_fgColor);
        p.setWidth(m_borderWidth);
        painter.setPen(p);

        QPainterPath pt;
        if (m_zintSymbol->symbology != BARCODE_MAXICODE) {
            /* Draw boundary bars or boxes around the symbol */
            switch (m_border) {

                case BOX:
                    painter.fillRect(0, m_borderWidth, m_borderWidth, m_zintSymbol->height, QBrush(m_fgColor));
                    painter.fillRect(m_zintSymbol->width + xoffset + xoffset + m_borderWidth, m_borderWidth, m_borderWidth, m_zintSymbol->height, QBrush(m_fgColor));
                    painter.fillRect(0, 0, m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth, QBrush(m_fgColor));
                    painter.fillRect(0, m_zintSymbol->height + m_borderWidth, m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth, QBrush(m_fgColor));
                    painter.translate(m_borderWidth + m_zintSymbol->whitespace_width, m_borderWidth);
                    yoffset = m_borderWidth;
                    break;
                case BIND:
                    if (m_zintSymbol->symbology != BARCODE_CODABLOCKF) {
                        painter.fillRect(0, 0, m_zintSymbol->width + xoffset + xoffset, m_borderWidth, QBrush(m_fgColor));
                        painter.fillRect(0, m_zintSymbol->height, m_zintSymbol->width + xoffset + xoffset, m_borderWidth, QBrush(m_fgColor));
                    } else {
                        painter.fillRect(xoffset, 0, m_zintSymbol->width, m_borderWidth, QBrush(m_fgColor));
                        painter.fillRect(xoffset, m_zintSymbol->height, m_zintSymbol->width, m_borderWidth, QBrush(m_fgColor));
                    }
                    painter.translate(m_zintSymbol->whitespace_width, m_borderWidth);
                    yoffset = m_borderWidth;
                    break;

                default:
                    painter.translate(m_zintSymbol->whitespace_width, 0);
                    break;
                    ;
            }
        }

        while (!(module_set(m_zintSymbol->rows - 1, comp_offset))) {
            comp_offset++;
        }
        xoffset = comp_offset;

        /* Set up some values for displaying EAN and UPC symbols correctly */
        main_width = m_zintSymbol->width;
        if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC))
                || (m_zintSymbol->symbology == BARCODE_ISBNX)) {
            switch (caption.size()) {
                case 13: /* EAN 13 */
                case 16:
                case 19:
                    if (m_zintSymbol->whitespace_width == 0) {
                        m_zintSymbol->whitespace_width = 10;
                    }
                    main_width = 96 + comp_offset;
                    break;
                default:
                    main_width = 68 + comp_offset;
                    break;
            }
        }

        if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
            if (m_zintSymbol->whitespace_width == 0) {
                m_zintSymbol->whitespace_width = 10;
            }
            main_width = 96 + comp_offset;
        }

        if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
            if (m_zintSymbol->whitespace_width == 0) {
                m_zintSymbol->whitespace_width = 10;
            }
            main_width = 51 + comp_offset;
        }

        p.setWidth(1);
        painter.setPen(p);

        if (m_zintSymbol->symbology == BARCODE_MAXICODE) {

            /* Draw Maxicode with hexagons */
            painter.save();
            painter.setRenderHint(QPainter::Antialiasing);
            for (int r = 0; r < m_zintSymbol->rows; r++) {

                for (int c = 0; c < m_zintSymbol->width; c++) {

                    if (module_set(r, c)) {

                        qreal col = (qreal) c * (maxi_width + 1)+(r % 2)*((maxi_width + 1) / 2);
                        qreal row = (qreal) r * (maxi_width + 1)*0.868;
                        QPainterPath pt;
                        pt.moveTo(col + maxi_width / 2, row);
                        pt.lineTo(col + maxi_width, row + maxi_diagonal / 4);
                        pt.lineTo(col + maxi_width, row + (maxi_diagonal - maxi_diagonal / 4));
                        pt.lineTo(col + maxi_width / 2, row + maxi_diagonal);
                        pt.lineTo(col, row + (maxi_diagonal - maxi_diagonal / 4));
                        pt.lineTo(col, row + maxi_diagonal / 4);
                        pt.lineTo(col + maxi_width / 2, row);
                        painter.fillPath(pt, QBrush(m_fgColor));
                    }
                }
            }
            p.setWidth(maxi_width);
            painter.setPen(p);
            const qreal w = maxi_width + 1;
            painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w, w);
            painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w + w * 1.5, w + w * 1.5);
            painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w + w * 3, w + w * 3);
            painter.restore();
        } else if (m_zintSymbol->output_options & BARCODE_DOTTY_MODE) {
            /* Draw with dots (circles) */

            p.setColor(m_fgColor);
            p.setWidth(0);
            painter.setPen(p);
            painter.setBrush(QBrush(m_fgColor));
            painter.setRenderHint(QPainter::Antialiasing);
            for (int r = 0; r < m_zintSymbol->rows; r++) {
                for (int c = 0; c < m_zintSymbol->width; c++) {
                    if (module_set(r, c)) {

                        painter.drawEllipse(QPointF((c + 1.0), (r + 1.0)), m_dot_size / 2.0, m_dot_size / 2.0);
                    }
                }
            }
        } else {
            /* Draw all other symbols with rectangles */
            int y = 0;
            for (int row = 0; row < m_zintSymbol->rows; row++) {

                for (int i = 0; i < m_zintSymbol->width; i++) {
                    if (module_set(row, i)) {

                        int ed = module_set(row, i);
                        int linewidth = 0;
                        for (int j = i; j < m_zintSymbol->width; j++, linewidth++)
                            if (ed != module_set(row, j))
                                break;
                        QColor color;
                        color = m_fgColor;

                        if (!((i > main_width) && (row == m_zintSymbol->rows - 1))) {
                            painter.fillRect(i, y, linewidth, m_zintSymbol->row_height[row], QBrush(color));
                        } else {
                            painter.fillRect(i, y + 8, linewidth, m_zintSymbol->row_height[row] - 3, QBrush(color));
                            addon_text_height = y;
                        }
                    }
                }
                /* Add row binding */
                if (((m_zintSymbol->symbology == BARCODE_CODE16K) 
                        || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) {
                    painter.fillRect(0, y - 1, m_zintSymbol->width, 2, QBrush(m_fgColor));
                }
                if ((m_zintSymbol->symbology == BARCODE_CODABLOCKF) && (row != 0)) {
                    painter.fillRect(11, y - 1, m_zintSymbol->width - 25, 2, QBrush(m_fgColor));
                }
                y += m_zintSymbol->row_height[row];
            }
        }

        textdone = false;

        if (m_hidetext == false) {
            painter.setFont(fontSmall);
            if (((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) ||
                    (m_zintSymbol->symbology == BARCODE_ISBNX)) {
                /* Add bridge and format text for EAN */
                switch (caption.size()) {
                    case 8:
                    case 11:
                    case 14:
                        painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(32 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(34 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(64 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(66 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.setFont(fontLarge);
                        painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9, Qt::AlignCenter, caption.mid(0, 4));
                        painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9, Qt::AlignCenter, caption.mid(4, 4));
                        if (caption.size() == 11) {
                            /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(9, 2));
                        };
                        if (caption.size() == 14) {
                            /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(9, 5));
                        };
                        painter.setFont(fontSmall);
                        textdone = true;
                        break;
                    case 13:
                    case 16:
                    case 19:
                        painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(92 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.fillRect(94 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                        painter.setFont(fontLarge);
                        painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9, Qt::AlignCenter, caption.mid(0, 1));
                        painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(1, 6));
                        painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(7, 6));
                        if (caption.size() == 16) {
                            /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(14, 2));
                        };
                        if (caption.size() == 19) {
                            /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(14, 5));
                        };
                        painter.setFont(fontSmall);
                        textdone = true;
                        break;
                }
                if (textdone == false) {
                    painter.setFont(fontLarge);
                    painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9, Qt::AlignCenter, caption);
                    painter.setFont(fontSmall);
                    textdone = true;
                }
            }

            if ((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
                /* Add bridge and format text for UPC-A */
                int block_width;
                bool latch = true;

                j = 0 + comp_offset;
                do {
                    block_width = 0;
                    do {
                        block_width++;
                    } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
                    if (latch == true) {
                        /* a bar */
                        painter.fillRect(j + xoffset - comp_offset, m_zintSymbol->height, block_width, 5, QBrush(m_fgColor));
                        latch = false;
                    } else {
                        /* a space */
                        latch = true;
                    }
                    j += block_width;
                } while (j < 11 + comp_offset);
                painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                latch = true;
                j = 85 + comp_offset;
                do {
                    block_width = 0;
                    do {
                        block_width++;
                    } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
                    if (latch == true) {
                        /* a bar */
                        painter.fillRect(j + xoffset - comp_offset, m_zintSymbol->height, block_width, 5, QBrush(m_fgColor));
                        latch = false;
                    } else {
                        /* a space */
                        latch = true;
                    }
                    j += block_width;
                } while (j < 96 + comp_offset);
                painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(0, 1));
                painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(11, 1));
                painter.setFont(fontLarge);
                painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9, Qt::AlignCenter, caption.mid(1, 5));
                painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9, Qt::AlignCenter, caption.mid(6, 5));
                if (caption.size() == 15) {
                    /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(13, 2));
                };
                if (caption.size() == 18) {
                    /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(13, 5));
                };
                painter.setFont(fontSmall);
                textdone = true;
            }

            if ((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
                /* Add bridge and format text for UPC-E */
                painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.fillRect(50 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor));
                painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(0, 1));
                painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(7, 1));
                painter.setFont(fontLarge);
                painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(1, 6));
                if (caption.size() == 11) {
                    /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(9, 2));
                };
                if (caption.size() == 14) {
                    /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(9, 5));
                };
                painter.setFont(fontSmall);
                textdone = true;
            }
        } /* if (m_hidetext == false) */

        if ((m_hidetext == false) && (textdone == false)) {
            /* Add text to any other symbol */
            painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption);
        }
        painter.restore();
    }

    const QString & QZint::lastError() {

        return m_lastError;
    }

    bool QZint::hasErrors() {

        return m_lastError.length();
    }

}

Changes to jni/zint/backend_qt4/qzint.h.
69
70
71
72
73
74
75


76
77
78
79
80
81
82
	void setPdf417CodeWords(int pdf417CodeWords);

	int securityLevel();
	void setSecurityLevel(int securityLevel);

	float scale();
	void setScale(float scale);



	int mode();
	void setMode(int securityLevel);

	void setInputMode(int input_mode);

	void setWhitespace(int whitespace);







>
>







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
	void setPdf417CodeWords(int pdf417CodeWords);

	int securityLevel();
	void setSecurityLevel(int securityLevel);

	float scale();
	void setScale(float scale);
        
        void setDotSize(float dot_size);

	int mode();
	void setMode(int securityLevel);

	void setInputMode(int input_mode);

	void setWhitespace(int whitespace);
112
113
114
115
116
117
118

119
120
121
	QString m_lastError;
	int m_error;
	int m_whitespace;
	zint_symbol * m_zintSymbol;
	float m_scale;
	int m_option_3;
	bool m_hidetext;

};
}
#endif







>



114
115
116
117
118
119
120
121
122
123
124
	QString m_lastError;
	int m_error;
	int m_whitespace;
	zint_symbol * m_zintSymbol;
	float m_scale;
	int m_option_3;
	bool m_hidetext;
        float m_dot_size;
};
}
#endif
Changes to jni/zint/backend_tcl/configure.
1
2
3
4
5
6
7
8
9
10
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for zint 2.5.0.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##


|







1
2
3
4
5
6
7
8
9
10
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for zint 2.5.2.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='zint'
PACKAGE_TARNAME='zint'
PACKAGE_VERSION='2.5.0'
PACKAGE_STRING='zint 2.5.0'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>







|
|







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='zint'
PACKAGE_TARNAME='zint'
PACKAGE_VERSION='2.5.2'
PACKAGE_STRING='zint 2.5.2'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures zint 2.5.0 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.







|







1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures zint 2.5.2 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of zint 2.5.0:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]







|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of zint 2.5.2:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
zint configure 2.5.0
generated by GNU Autoconf 2.63

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by zint $as_me 2.5.0, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{







|













|







1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
zint configure 2.5.2
generated by GNU Autoconf 2.63

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by zint $as_me 2.5.2, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
7884
7885
7886
7887
7888
7889
7890


7891
7892
7893
7894
7895
7896
7897
7898
7899



7900
7901

7902
7903
7904
7905
7906

7907
7908
7909
7910
7911
7912

7913
7914
7915
7916
7917
7918
7919
#-----------------------------------------------------------------------


    vars="
	../backend/2of5.c
	../backend/auspost.c
	../backend/aztec.c


	../backend/code128.c
	../backend/code16k.c
	../backend/code1.c
	../backend/code49.c
	../backend/code.c
	../backend/common.c
	../backend/composite.c
	../backend/dllversion.c
	../backend/dmatrix.c



	../backend/gridmtx.c
	../backend/gs1.c

	../backend/imail.c
	../backend/large.c
	../backend/library.c
	../backend/maxicode.c
	../backend/medical.c

	../backend/pdf417.c
	../backend/plessey.c
	../backend/png.c
	../backend/postal.c
	../backend/ps.c
	../backend/qr.c

	../backend/reedsol.c
	../backend/render.c
	../backend/rss.c
	../backend/svg.c
	../backend/telepen.c
	../backend/upcean.c
	zint.c







>
>









>
>
>


>





>






>







7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
#-----------------------------------------------------------------------


    vars="
	../backend/2of5.c
	../backend/auspost.c
	../backend/aztec.c
	../backend/bmp.c
	../backend/codablock.c
	../backend/code128.c
	../backend/code16k.c
	../backend/code1.c
	../backend/code49.c
	../backend/code.c
	../backend/common.c
	../backend/composite.c
	../backend/dllversion.c
	../backend/dmatrix.c
	../backend/dotcode.c
	../backend/eci.c
	../backend/gif.c
	../backend/gridmtx.c
	../backend/gs1.c
	../backend/hanxin.c
	../backend/imail.c
	../backend/large.c
	../backend/library.c
	../backend/maxicode.c
	../backend/medical.c
	../backend/pcx.c
	../backend/pdf417.c
	../backend/plessey.c
	../backend/png.c
	../backend/postal.c
	../backend/ps.c
	../backend/qr.c
	../backend/raster.c
	../backend/reedsol.c
	../backend/render.c
	../backend/rss.c
	../backend/svg.c
	../backend/telepen.c
	../backend/upcean.c
	zint.c
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971

exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by zint $as_me 2.5.0, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@







|







12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979

exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by zint $as_me 2.5.2, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
$config_files

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
zint config.status 2.5.0
configured by $0, generated by GNU Autoconf 2.63,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."








|







13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
$config_files

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
zint config.status 2.5.2
configured by $0, generated by GNU Autoconf 2.63,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Changes to jni/zint/backend_tcl/configure.in.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
#-----------------------------------------------------------------------

AC_INIT([zint], [2.5.0])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------








|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
#-----------------------------------------------------------------------

AC_INIT([zint], [2.5.2])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81



82
83

84
85
86
87
88

89
90
91
92
93
94

95
96
97
98
99
100
101
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([
	../backend/2of5.c
	../backend/auspost.c
	../backend/aztec.c


	../backend/code128.c
	../backend/code16k.c
	../backend/code1.c
	../backend/code49.c
	../backend/code.c
	../backend/common.c
	../backend/composite.c
	../backend/dllversion.c
	../backend/dmatrix.c



	../backend/gridmtx.c
	../backend/gs1.c

	../backend/imail.c
	../backend/large.c
	../backend/library.c
	../backend/maxicode.c
	../backend/medical.c

	../backend/pdf417.c
	../backend/plessey.c
	../backend/png.c
	../backend/postal.c
	../backend/ps.c
	../backend/qr.c

	../backend/reedsol.c
	../backend/render.c
	../backend/rss.c
	../backend/svg.c
	../backend/telepen.c
	../backend/upcean.c
	zint.c







>
>









>
>
>


>





>






>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([
	../backend/2of5.c
	../backend/auspost.c
	../backend/aztec.c
	../backend/bmp.c
	../backend/codablock.c
	../backend/code128.c
	../backend/code16k.c
	../backend/code1.c
	../backend/code49.c
	../backend/code.c
	../backend/common.c
	../backend/composite.c
	../backend/dllversion.c
	../backend/dmatrix.c
	../backend/dotcode.c
	../backend/eci.c
	../backend/gif.c
	../backend/gridmtx.c
	../backend/gs1.c
	../backend/hanxin.c
	../backend/imail.c
	../backend/large.c
	../backend/library.c
	../backend/maxicode.c
	../backend/medical.c
	../backend/pcx.c
	../backend/pdf417.c
	../backend/plessey.c
	../backend/png.c
	../backend/postal.c
	../backend/ps.c
	../backend/qr.c
	../backend/raster.c
	../backend/reedsol.c
	../backend/render.c
	../backend/rss.c
	../backend/svg.c
	../backend/telepen.c
	../backend/upcean.c
	zint.c
Changes to jni/zint/backend_tcl/lib/zint/pkgIndex.tcl.
1
2
package ifneeded zint 2.5.0\
    [list load [file join $dir zint[info sharedlibextension]]]
|

1
2
package ifneeded zint 2.5.2\
    [list load [file join $dir zint[info sharedlibextension]]]
Changes to jni/zint/backend_tcl/zint.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35





36
37
38
39
40
41
42
/* zint_tcl.c TCL binding for zint */
/*
    zint - the open source tcl binding to the zint barcode library
    Copyright (C) 2014 Harald Oehlmann <oehhar@users.sourceforge.net>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright 
       notice, this list of conditions and the following disclaimer.  
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.  
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission. 

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    SUCH DAMAGE.
*/
/*
 History

  2014-06-16 2.5.0 HaO
	First implementation





*/

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#pragma warning(disable : 4201 4214 4514)
#define STRICT
#define WIN32_LEAN_AND_MEAN
/* TCL Defines */









|
|


|


|










|






|
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/* zint_tcl.c TCL binding for zint */
/*
    zint - the open source tcl binding to the zint barcode library
    Copyright (C) 2014 Harald Oehlmann <oehhar@users.sourceforge.net>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
*/
/*
 History

  2014-06-16 2.5.0 HaO
    First implementation
 2016-09-14 2.5.1 HaO
-   Added Codablock F options "-rows".
-   Adopted to new image format of zint
 2016-10-14 2.5.2 HaO
-   Include the upstream reverted image format
*/

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#pragma warning(disable : 4201 4214 4514)
#define STRICT
#define WIN32_LEAN_AND_MEAN
/* TCL Defines */
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267


268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717


718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#define USE_TCL_STUBS
#define USE_TK_STUBS
#endif

#include <tcl.h>
#include <tk.h> 

#undef EXPORT
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif


/*----------------------------------------------------------------------------*/
/* > File option defines */

#define VERSION "2.5.0"

/*----------------------------------------------------------------------------*/
/* >>>>> Hepler defines */

#define STRING( x ) #x

/*----------------------------------------------------------------------------*/
/* >>>> External Prototypes (exports) */
EXPORT int Zint_Init (Tcl_Interp *interp);
/*----------------------------------------------------------------------------*/
/* >>>> local prototypes */
static int Zint(ClientData unused, Tcl_Interp *interp, int objc, 
	Tcl_Obj *CONST objv[]);
static int Encode(Tcl_Interp *interp, int objc, 
	Tcl_Obj *CONST objv[]);
/*----------------------------------------------------------------------------*/
/* >>>> File Global Variables */

/* >> List of Codes */

static char *s_code_list[] = {
        "Code11",
        "Matrix2of5",
        "Interleaved2of5",
        "IATAC2of5",
        "Logic2of5",
        "Ind2of5",
        "Code39",
        "Code39Extended",
        "EAN",
        "GS1-128",
        "Codabar",
        "Code128",
        "DPLeit",
        "DPIdent",
        "Code16K",
        "Code49",
        "Code93",
        "Flat",
        "GS1DataBar",
        "GS1DataBarLimited",
        "GS1DataBarExpanded",
        "Telepen",
        "UPC-A",
        "UPC-E",
        "Postnet",
        "MSIPlessey",
        "FIM",
        "Logmars",
        "Pharma",
        "PZN",
        "PharmaTwo",
        "PDF417",
        "PDF417Truncated",
        "MaxiCode",
        "QR",
        "Code128B",
        "AusPost",
        "AusReply",
        "AusRoute",
        "AusRedirect",
        "ISBN",
        "RM4SCC",
        "Datamatrix",
        "EAN14",
        "CodablockF",
        "NVE18",
        "JapanPost",
        "KoreaPost",
        "RSS14Stacked",
        "RSS14SstackedOmni",
        "RSSExpandedStacked",
        "Planet",
        "MicroPDF417",
        "OneCode",
        "Plessey",
        "TelepenNum",
        "ITF14",
        "KIX",
        "Aztec",
        "DAFT",
        "MicroQR",
        "HIBC-128",
        "HIBC-39",
        "HIBC-DM",
        "HIBC-QR",
        "HIBC-PDF",
        "HIBC-MicroPDF",
        "HIBC-CodablockF",
        "HIBCAztec",
        "Azure",
        "Code32",
        "EAN-CC",
        "EAN128-CC",
        "RSS14-CC",
        "RSSLimited-CC",
        "RSSEXPanded-CC",
        "UPCA-CC",
        "UPCE-CC",
        "RSS14Stacked-CC",
        "RSS14Omni-CC",
        "RSSExpandedStacked-CC",
        "Channel",
        "CodeOne",
        "GridMatrix",


        NULL};

static int s_code_number[] = {
        BARCODE_CODE11,
        BARCODE_C25MATRIX,
        BARCODE_C25INTER,
        BARCODE_C25IATA,
        BARCODE_C25LOGIC,
        BARCODE_C25IND,
        BARCODE_CODE39,
        BARCODE_EXCODE39,
        BARCODE_EANX,
        BARCODE_EAN128,
        BARCODE_CODABAR,
        BARCODE_CODE128,
        BARCODE_DPLEIT,
        BARCODE_DPIDENT,
        BARCODE_CODE16K,
        BARCODE_CODE49,
        BARCODE_CODE93,
        BARCODE_FLAT,
        BARCODE_RSS14,
        BARCODE_RSS_LTD,
        BARCODE_RSS_EXP,
        BARCODE_TELEPEN,
        BARCODE_UPCA,
        BARCODE_UPCE,
        BARCODE_POSTNET,
        BARCODE_MSI_PLESSEY,
        BARCODE_FIM,
        BARCODE_LOGMARS,
        BARCODE_PHARMA,
        BARCODE_PZN,
        BARCODE_PHARMA_TWO,
        BARCODE_PDF417,
        BARCODE_PDF417TRUNC,
        BARCODE_MAXICODE,
        BARCODE_QRCODE,
        BARCODE_CODE128B,
        BARCODE_AUSPOST,
        BARCODE_AUSREPLY,
        BARCODE_AUSROUTE,
        BARCODE_AUSREDIRECT,
        BARCODE_ISBNX,
        BARCODE_RM4SCC,
        BARCODE_DATAMATRIX,
        BARCODE_EAN14,
        BARCODE_CODABLOCKF,
        BARCODE_NVE18,
        BARCODE_JAPANPOST,
        BARCODE_KOREAPOST,
        BARCODE_RSS14STACK,
        BARCODE_RSS14STACK_OMNI,
        BARCODE_RSS_EXPSTACK,
        BARCODE_PLANET,
        BARCODE_MICROPDF417,
        BARCODE_ONECODE,
        BARCODE_PLESSEY,
        BARCODE_TELEPEN_NUM,
        BARCODE_ITF14,
        BARCODE_KIX,
        BARCODE_AZTEC,
        BARCODE_DAFT,
        BARCODE_MICROQR,
        BARCODE_HIBC_128,
        BARCODE_HIBC_39,
        BARCODE_HIBC_DM,
        BARCODE_HIBC_QR,
        BARCODE_HIBC_PDF,
        BARCODE_HIBC_MICPDF,
        BARCODE_HIBC_BLOCKF,
        BARCODE_HIBC_AZTEC,
        BARCODE_AZRUNE,
        BARCODE_CODE32,
        BARCODE_EANX_CC,
        BARCODE_EAN128_CC,
        BARCODE_RSS14_CC,
        BARCODE_RSS_LTD_CC,
        BARCODE_RSS_EXP_CC,
        BARCODE_UPCA_CC,
        BARCODE_UPCE_CC,
        BARCODE_RSS14STACK_CC,
        BARCODE_RSS14_OMNI_CC,
        BARCODE_RSS_EXPSTACK_CC,
        BARCODE_CHANNEL,
        BARCODE_CODEONE,
        BARCODE_GRIDMATRIX,


        0};


/* Version information */
static char version_string[] = VERSION;
/* Help text */
static char help_message[] = "zint tcl(stub,obj) dll\n"
	"(c) 2014-06-16 ELMICRON GmbH by Harald Oehlmann\n"
	" Generate barcode in tk images and in file output\n"
	"Usage:\n"
	" zint encode option value...\n"
	"  Available options:\n"
	"   -bind bool: bars above/below the code, size set by -border\n"
	"   -box bool: box around bar code, size set be -border\n"
	"   -barcode choice: symbology, use 'zint symbology' to get a list\n"
	"   -height integer: Symbol height in modules\n"
	"   -whitesp integer: horizontal quiet zone in modules\n"
	"   -border integer: with of a border around the symbol. Use with -bind/-box 1\n"
	"   -fg color: set foreground color as 6 hex rrggbb\n"
	"   -bg color: set background color as 6 hex rrggbb\n"
	"   -cols integer: PDF417: number of columns\n"

	"   -vers integer: Symbology option, QR-Code, Plessy\n"
	"   -rotate angle: Image rotation by 0,90 or 270 degrees\n"
	"   -secure integer: EC Level (PDF417, QR)\n"
	"   -mode: Structured primary data mode (Maxicode, Composite)\n"
	"   -primary text: Structured primary data (Maxicode, Composite)\n"
	"   -scale double: Scale the image to this factor\n"
    "   -format binary|unicode|gs1: input data format. Default:unicode"
	"   -notext bool: no interpretation line\n"
	"   -square bool: force Data Matrix symbols to be square\n"
	"   -init bool: Create reader initialisation symbol (Code 128, Data Matrix)\n"
	"   -smalltext bool: tiny interpretation line font\n"
	"   -to {x0 y0 ?width? ?height?}: place to put in photo image\n"
	"\n"
	"zint symbologies: List available symbologies\n"
	" zint help\n"
	" zint version\n"
	;

/*----------------------------------------------------------------------------*/
/* Exported symbols */
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
EXPORT BOOL WINAPI DllEntryPoint (HINSTANCE hInstance, 
	DWORD seginfo, LPVOID lpCmdLine)
{
  /* Don't do anything, so just return true */
  return TRUE;
}
#endif
/*----------------------------------------------------------------------------*/
/* Initialisation Procedures */
EXPORT int Zint_Init (Tcl_Interp *Interp)
{
	/*------------------------------------------------------------------------*/
#ifdef USE_TCL_STUBS
	if (Tcl_InitStubs(Interp, "8.1", 0) == NULL)
#else
	if (Tcl_PkgRequire(Interp, "Tcl", "8.1", 0) == NULL)
#endif
	{
		return TCL_ERROR;
	}
	/*------------------------------------------------------------------------*/
#ifdef USE_TK_STUBS
	if (Tk_InitStubs(Interp, "8.1", 0) == NULL)
#else
	if (Tcl_PkgRequire(Interp, "Tk", "8.1", 0) == NULL)
#endif
	{
		return TCL_ERROR;
	}
	/*------------------------------------------------------------------------*/
	Tcl_CreateObjCommand(Interp, "zint", Zint, (ClientData)NULL,
		(Tcl_CmdDeleteProc *)NULL);
	Tcl_PkgProvide (Interp, "zint", version_string);
	/*------------------------------------------------------------------------*/
	return TCL_OK;
}
/*----------------------------------------------------------------------------*/
/* >>>>> Called routine */
/*----------------------------------------------------------------------------*/
/* Decode tcl commands */
static int Zint(ClientData unused, Tcl_Interp *interp, int objc, 
	Tcl_Obj *CONST objv[])
{
	/* Option list and indexes */
	char *subCmds[] = {"encode", "symbologies", "version", "help", NULL};
	enum iCommand {iEncode, iSymbologies, iVersion, iHelp};
	/* choice of option */
	int Index;
	/*------------------------------------------------------------------------*/
	/* > Check if option argument is given and decode it */
	if (objc > 1)
	{
		if(Tcl_GetIndexFromObj(interp, objv[1], (const char **) subCmds,
			"option", 0, &Index) 
			== TCL_ERROR)
		{
			return TCL_ERROR;
		}
	} else {
		Tcl_WrongNumArgs(interp, 1, objv, "option");
		return TCL_ERROR;
	}
	/*------------------------------------------------------------------------*/
	/* > Call functions in dependency of Index */
	/*------------------------------------------------------------------------*/
	switch (Index)
	{
	case iEncode:
		return Encode(interp, objc, objv);
	case iSymbologies:
        {
            Tcl_Obj *oRes;
            int posCur;
            oRes = Tcl_NewObj();
            for (posCur = 0 ; s_code_list[posCur] != NULL; posCur++) {
                if( ZBarcode_ValidID(s_code_number[posCur]) != 0) {
                    if (TCL_OK != Tcl_ListObjAppendElement(interp,
                            oRes, Tcl_NewStringObj(s_code_list[posCur],-1)))
                    {
                        return TCL_ERROR;
                    }
                }
            }
            Tcl_SetObjResult(interp,oRes);
            return TCL_OK;
        }
	case iVersion:
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(version_string, -1));
		return TCL_OK;
	case iHelp:
	default:
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(help_message, -1));
		return TCL_OK;
	}
}
/*----------------------------------------------------------------------------*/
/* >>>>> Encode */
/*----------------------------------------------------------------------------*/
/* Encode image */
static int Encode(Tcl_Interp *interp, int objc, 
	Tcl_Obj *CONST objv[])
{
	struct zint_symbol *hSymbol;
	Tcl_DString dsInput;
	char *pStr = NULL;
	int lStr;
	Tcl_Encoding hUTF8Encoding;
	int rotate_angle=0;
	int fError = 0;
	Tcl_DString dString;
	int optionPos;
	int destX0 = 0;
	int destY0 = 0;
	int destWidth = 0;
	int destHeight = 0;
	/*------------------------------------------------------------------------*/
	/* >> Check if at least data and object is given and a pair number of */
	/* >> options */
	if ( objc < 4 || (objc % 2) != 0 )
	{
		Tcl_WrongNumArgs(interp, 2, objv, "data photo ?-switch value?...");
		return TCL_ERROR;
	}
	/*------------------------------------------------------------------------*/
	/* >>> Prepare encoding */
	hUTF8Encoding = Tcl_GetEncoding(interp, "utf-8");
	if (NULL == hUTF8Encoding) {
		return TCL_ERROR;
	}
	/*------------------------------------------------------------------------*/
	/* >>> Prepare zint object */
	hSymbol = ZBarcode_Create();
	hSymbol->input_mode = UNICODE_MODE;
	/*------------------------------------------------------------------------*/
	/* >> Decode options */
	for (optionPos = 4; optionPos < objc; optionPos+=2) {
		/*--------------------------------------------------------------------*/
		/* Option list and indexes */
		char *optionList[] = {
			"-bind", "-box", "-barcode", "-height", "-whitesp", "-border",
			"-fg", "-bg", "-cols", "-vers", "-rotate",
			"-secure", "-mode", "-primary", "-scale", "-format",
			"-notext", "-square", "-dmre", "-init", "-smalltext", "-to",
			NULL};
		enum iOption {
			iBind, iBox, iBarcode, iHeight, iWhiteSp, iBorder,
			iFG, iBG, iCols, iVers, iRotate,
			iSecure, iMode, iPrimary, iScale, iFormat,
			iNoText, iSquare, iDMRE, iInit, iSmallText, iTo
			};
		int optionIndex;
		int intValue;
		double doubleValue;
		/*--------------------------------------------------------------------*/
		if(Tcl_GetIndexFromObj(interp, objv[optionPos],
			(const char **) optionList,
			"zint option", optionPos-1, &optionIndex) 
			== TCL_ERROR)
		{
			fError = 1;
			break;
		}
		/*--------------------------------------------------------------------*/
		/* >> Decode object */
		switch (optionIndex) {
		case iBind:
		case iBox:
		case iInit:
		case iSmallText:
		case iNoText:
		case iSquare:
		case iDMRE:
			/* >> Binary options */
			if (TCL_OK != Tcl_GetBooleanFromObj(interp, objv[optionPos+1],
					&intValue))
			{
				fError = 1;
			}
			break;
		case iFG:
		case iBG:
			/* >> Colors */
			pStr = Tcl_GetStringFromObj(objv[optionPos+1],&lStr);
			if (lStr != 6) {
				Tcl_SetObjResult(interp,
						Tcl_NewStringObj("Color is not 6 hex",-1));
				fError = 1;
			}
			break;
		case iScale:
			/* >> Float */
			if (TCL_OK != Tcl_GetDoubleFromObj(interp, objv[optionPos+1],
					&doubleValue))
			{
				fError = 1;
			}
			break;
		case iBorder:
		case iHeight:
		case iCols:

		case iVers:
		case iSecure:
		case iMode:
		case iRotate:
		case iWhiteSp:
			/* >> Int */
			if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1],
					&intValue))
			{
				fError = 1;
			}
			break;
		case iPrimary:
			/* > Primary String up to 90 characters */
			/* > Output filename up to 250 characters */
			Tcl_DStringInit(& dString);
			pStr = Tcl_GetStringFromObj(objv[optionPos+1], &lStr);
			Tcl_UtfToExternalDString( hUTF8Encoding, pStr, lStr, &dString);
			if (Tcl_DStringLength(&dString) > (optionIndex==iPrimary?90:250)) {
				Tcl_DStringFree(&dString);
				Tcl_SetObjResult(interp,Tcl_NewStringObj("String to long", -1));
				fError = 1;
			}
			break;
		}
		if (fError) {
			break;
		}
		/*--------------------------------------------------------------------*/
		switch (optionIndex) {
		case iBind:
			if (intValue) {
				hSymbol->output_options |= BARCODE_BIND;
			} else {
				hSymbol->output_options &= ~BARCODE_BIND;
			}
			break;
		case iBox:
			if (intValue) {
				hSymbol->output_options |= BARCODE_BOX;
			} else {
				hSymbol->output_options &= ~BARCODE_BOX;
			}
			break;
		case iInit:
			if (intValue) {
				hSymbol->output_options |= READER_INIT;
			} else {
				hSymbol->output_options &= ~READER_INIT;
			}
			break;
		case iSmallText:
			if (intValue) {
				hSymbol->output_options |= SMALL_TEXT;
			} else {
				hSymbol->output_options &= ~SMALL_TEXT;
			}
			break;
		case iFG:
			strncpy(hSymbol->fgcolour, pStr, 6);
			hSymbol->fgcolour[6]='\0';
			break;
		case iBG:
			strncpy(hSymbol->bgcolour, pStr, 6);
			hSymbol->bgcolour[6]='\0';
			break;
		case iNoText:
			hSymbol->show_hrt = (intValue?0:1);
			break;
		case iSquare:
			hSymbol->option_3 = (intValue?DM_SQUARE:0);
			break;
		case iDMRE:
			/* DM_SQUARE overwrites DM_DMRE */
			if (hSymbol->option_3 != DM_DMRE) {
				hSymbol->option_3 = (intValue?DM_DMRE:0);
			}
			break;
		case iScale:
            if (doubleValue < 0.01) {
				Tcl_SetObjResult(interp,
                        Tcl_NewStringObj("Scale below 0.01", -1));
				fError = 1;
            } else {
                hSymbol->scale = (float)doubleValue;
            }
			break;
		case iBorder:
            if (intValue < 0 || intValue > 1000) {
				Tcl_SetObjResult(interp,
                        Tcl_NewStringObj("Border out of range", -1));
				fError = 1;
            } else {
    			hSymbol->border_width = intValue;
            }
			break;
		case iHeight:
            if (intValue < 1 || intValue > 1000) {
				Tcl_SetObjResult(interp,
                        Tcl_NewStringObj("Height out of range", -1));
				fError = 1;
            } else {
    			hSymbol->height = intValue;
            }
			break;
		case iCols:
		case iVers:
			/* >> Int in Option 2 */
            if (intValue < 1
                    || (optionIndex==iCols && intValue > 30)
                    || (optionIndex==iVers && intValue > 47))
            {
				Tcl_SetObjResult(interp,
                        Tcl_NewStringObj("cols/vers out of range", -1));
				fError = 1;
            } else {
    			hSymbol->option_2 = intValue;
            }
			break;
		case iSecure:
		case iMode:

			/* >> Int in Option 1 */
            if ( (optionIndex==iSecure && (intValue < 1 || intValue > 8))
                    || (optionIndex==iMode && (intValue < 0 || intValue > 6)))

            {
				Tcl_SetObjResult(interp,
                        Tcl_NewStringObj("secure/mode out of range", -1));
				fError = 1;
            } else {
    			hSymbol->option_1 = intValue;
            }
			break;
		case iPrimary:
			strcpy(hSymbol->primary, Tcl_DStringValue( &dString ) );
			Tcl_DStringFree(&dString);
			break;
		case iRotate:
            /* >> Rotate angle */
            /*----------------------------------------------------------------*/
            {
                char *rotateList[] = {"0", "90", "180", "270", "360", NULL};
                enum iRotate { iRotate0, iRotate90, iRotate180, iRotate270 };
                /*------------------------------------------------------------*/
                if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                    (const char **) rotateList,
                    "rotate", optionPos, &intValue) 
                    == TCL_ERROR)
                {
                    fError = 1;
                    break;
                }
                switch (intValue) {
                    case iRotate90: rotate_angle = 90; break;
                    case iRotate180: rotate_angle = 180; break;
                    case iRotate270: rotate_angle = 270; break;
                    default: rotate_angle = 0; break;
                }
            }
			break;
		case iBarcode:
            if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                (const char **) s_code_list,"-barcode", optionPos, &intValue) 
                == TCL_ERROR)
            {
                fError = 1;
            } else {
                hSymbol->symbology = s_code_number[intValue];
            }
			break;
		case iWhiteSp:
			hSymbol->whitespace_width = intValue;
			break;
		case iTo:
            /* >> Decode the -to parameter as list of X0 Y0 ?Width Height? */
            {
                Tcl_Obj *poParam;
                if (TCL_OK != Tcl_ListObjLength(interp,
                        objv[optionPos+1], &lStr))
                {
                    fError = 1;
                } else if ( ! ( lStr == 2 || lStr == 4 ) ) {
                    Tcl_SetObjResult(interp,
                            Tcl_NewStringObj(
                            "option -to not a list of 2 or 4", -1));
                    fError = 1;
                } else if ((
                        TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                            0, &poParam)
                        || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destX0)
                        || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                            1, &poParam)
                        || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destY0)
                        || lStr == 4) && (
                        TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                            2, &poParam)
                        || TCL_OK != Tcl_GetIntFromObj(interp,poParam,
                            &destWidth)
                        || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                            3, &poParam)
                        || TCL_OK != Tcl_GetIntFromObj(interp,poParam,
                            &destHeight)
                        ))
                {
                    fError = 1;
                }			break;
            }


        case iFormat:
            /* >> Format of the input data */
            /*----------------------------------------------------------------*/
            {
                char *formatList[] = {"binary", "gs1", "unicode",NULL};
                enum iFormat { iBinary, iGS1, iUnicode };
                /*------------------------------------------------------------*/
                if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                    (const char **) formatList,
                    "format", optionPos, &intValue) 
                    == TCL_ERROR)
                {
                    fError = 1;
                    break;
                }
                switch (intValue) {
                    case iBinary: hSymbol->input_mode = DATA_MODE; break;
                    case iGS1: hSymbol->input_mode = GS1_MODE; break;
                    default: hSymbol->input_mode = UNICODE_MODE; break;
                }
            }
        }
	}
    /*------------------------------------------------------------------------*/
    /* >>> Prepare input dstring */
	Tcl_DStringInit(& dsInput);
	/*------------------------------------------------------------------------*/
	if (!fError) {
		/*--------------------------------------------------------------------*/
		/* >>> Do output */
        Tk_PhotoHandle hPhoto;
        /*--------------------------------------------------------------------*/
        /* >>> Get input - 2nd argument */
        if (hSymbol->input_mode == DATA_MODE) {
            /* Binary data */
            pStr = (char *) Tcl_GetByteArrayFromObj(objv[2], &lStr);
        } else {
            /* UTF8 Data */
            pStr = Tcl_GetStringFromObj(objv[2], &lStr);
            Tcl_UtfToExternalDString( hUTF8Encoding, pStr, lStr, &dsInput);
            pStr = Tcl_DStringValue( &dsInput );
            lStr = Tcl_DStringLength( &dsInput );
        }
        /*--------------------------------------------------------------------*/
        if( 0 != ZBarcode_Encode_and_Buffer(hSymbol,
                (unsigned char *) pStr, lStr, rotate_angle) )
        {
            /* >> Encode error */
            fError = 1;
            Tcl_SetObjResult(interp, Tcl_NewStringObj(hSymbol->errtxt, -1));
        } else if ( 
                NULL == (hPhoto = Tk_FindPhoto(interp, Tcl_GetString(objv[3]))))
        {
			Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("Unknown photo image", -1));
            fError = 1;
        } else {
            Tk_PhotoImageBlock sImageBlock;
            sImageBlock.pixelPtr = (unsigned char *) hSymbol->bitmap;
            sImageBlock.width = hSymbol->bitmap_width;
            sImageBlock.height = hSymbol->bitmap_height;
            sImageBlock.pitch = 3*hSymbol->bitmap_width;
            sImageBlock.pixelSize = 3;
            sImageBlock.offset[0] = 0;
            sImageBlock.offset[1] = 1;
            sImageBlock.offset[2] = 2;
            sImageBlock.offset[3] = 0;
            if (0 == destWidth) {
                destWidth = hSymbol->bitmap_width;
            }
            if (0 == destHeight) {
                destHeight = hSymbol->bitmap_height;
            }
            if (TCL_OK != Tk_PhotoPutBlock(interp, hPhoto, &sImageBlock,
                    destX0, destY0, destWidth, destHeight,
                    TK_PHOTO_COMPOSITE_OVERLAY))
            {
                fError = 1;
            }
        }
	}
	/*------------------------------------------------------------------------*/
	Tcl_FreeEncoding(hUTF8Encoding);
	Tcl_DStringFree(& dsInput);
	ZBarcode_Delete(hSymbol);
	/*------------------------------------------------------------------------*/
	if (fError) {
		return TCL_ERROR;
	}
	return TCL_OK;
}







|












|











|
|
|
|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|




|
|









|

|

|

|
|
|
|

|

|

|
|
|
|
|
|
|
|
|





|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







|








|
|
|
|
|
|
|
|
|
|





|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|



|
|

|
|
|

|

|
|

|
|
|

|

|
|
|
|

|
|

|
|
|

|

|
|
|
>
|

|
>

|
|
|

|

|
|
|
|
|
|








|












|
|

|






|
|
|
|
|




|




|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


<
|
>
>









|












|


|
|
|
|
|















|




|
|

|
|



















|
|




|
|
|
|
|
|
|
|
|
|

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#define USE_TCL_STUBS
#define USE_TK_STUBS
#endif

#include <tcl.h>
#include <tk.h>

#undef EXPORT
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif


/*----------------------------------------------------------------------------*/
/* > File option defines */

#define VERSION "2.5.2"

/*----------------------------------------------------------------------------*/
/* >>>>> Hepler defines */

#define STRING( x ) #x

/*----------------------------------------------------------------------------*/
/* >>>> External Prototypes (exports) */
EXPORT int Zint_Init (Tcl_Interp *interp);
/*----------------------------------------------------------------------------*/
/* >>>> local prototypes */
static int Zint(ClientData unused, Tcl_Interp *interp, int objc,
    Tcl_Obj *CONST objv[]);
static int Encode(Tcl_Interp *interp, int objc,
    Tcl_Obj *CONST objv[]);
/*----------------------------------------------------------------------------*/
/* >>>> File Global Variables */

/* >> List of Codes */

static char *s_code_list[] = {
    "Code11",
    "Matrix2of5",
    "Interleaved2of5",
    "IATAC2of5",
    "Logic2of5",
    "Ind2of5",
    "Code39",
    "Code39Extended",
    "EAN",
    "GS1-128",
    "Codabar",
    "Code128",
    "DPLeit",
    "DPIdent",
    "Code16K",
    "Code49",
    "Code93",
    "Flat",
    "GS1DataBar",
    "GS1DataBarLimited",
    "GS1DataBarExpanded",
    "Telepen",
    "UPC-A",
    "UPC-E",
    "Postnet",
    "MSIPlessey",
    "FIM",
    "Logmars",
    "Pharma",
    "PZN",
    "PharmaTwo",
    "PDF417",
    "PDF417Truncated",
    "MaxiCode",
    "QR",
    "Code128B",
    "AusPost",
    "AusReply",
    "AusRoute",
    "AusRedirect",
    "ISBN",
    "RM4SCC",
    "Datamatrix",
    "EAN14",
    "CodablockF",
    "NVE18",
    "JapanPost",
    "KoreaPost",
    "RSS14Stacked",
    "RSS14SstackedOmni",
    "RSSExpandedStacked",
    "Planet",
    "MicroPDF417",
    "OneCode",
    "Plessey",
    "TelepenNum",
    "ITF14",
    "KIX",
    "Aztec",
    "DAFT",
    "MicroQR",
    "HIBC-128",
    "HIBC-39",
    "HIBC-DM",
    "HIBC-QR",
    "HIBC-PDF",
    "HIBC-MicroPDF",
    "HIBC-CodablockF",
    "HIBCAztec",
    "Azure",
    "Code32",
    "EAN-CC",
    "EAN128-CC",
    "RSS14-CC",
    "RSSLimited-CC",
    "RSSEXPanded-CC",
    "UPCA-CC",
    "UPCE-CC",
    "RSS14Stacked-CC",
    "RSS14Omni-CC",
    "RSSExpandedStacked-CC",
    "Channel",
    "CodeOne",
    "GridMatrix",
    "DotCode",
    "HanXin",
    NULL};

static int s_code_number[] = {
    BARCODE_CODE11,
    BARCODE_C25MATRIX,
    BARCODE_C25INTER,
    BARCODE_C25IATA,
    BARCODE_C25LOGIC,
    BARCODE_C25IND,
    BARCODE_CODE39,
    BARCODE_EXCODE39,
    BARCODE_EANX,
    BARCODE_EAN128,
    BARCODE_CODABAR,
    BARCODE_CODE128,
    BARCODE_DPLEIT,
    BARCODE_DPIDENT,
    BARCODE_CODE16K,
    BARCODE_CODE49,
    BARCODE_CODE93,
    BARCODE_FLAT,
    BARCODE_RSS14,
    BARCODE_RSS_LTD,
    BARCODE_RSS_EXP,
    BARCODE_TELEPEN,
    BARCODE_UPCA,
    BARCODE_UPCE,
    BARCODE_POSTNET,
    BARCODE_MSI_PLESSEY,
    BARCODE_FIM,
    BARCODE_LOGMARS,
    BARCODE_PHARMA,
    BARCODE_PZN,
    BARCODE_PHARMA_TWO,
    BARCODE_PDF417,
    BARCODE_PDF417TRUNC,
    BARCODE_MAXICODE,
    BARCODE_QRCODE,
    BARCODE_CODE128B,
    BARCODE_AUSPOST,
    BARCODE_AUSREPLY,
    BARCODE_AUSROUTE,
    BARCODE_AUSREDIRECT,
    BARCODE_ISBNX,
    BARCODE_RM4SCC,
    BARCODE_DATAMATRIX,
    BARCODE_EAN14,
    BARCODE_CODABLOCKF,
    BARCODE_NVE18,
    BARCODE_JAPANPOST,
    BARCODE_KOREAPOST,
    BARCODE_RSS14STACK,
    BARCODE_RSS14STACK_OMNI,
    BARCODE_RSS_EXPSTACK,
    BARCODE_PLANET,
    BARCODE_MICROPDF417,
    BARCODE_ONECODE,
    BARCODE_PLESSEY,
    BARCODE_TELEPEN_NUM,
    BARCODE_ITF14,
    BARCODE_KIX,
    BARCODE_AZTEC,
    BARCODE_DAFT,
    BARCODE_MICROQR,
    BARCODE_HIBC_128,
    BARCODE_HIBC_39,
    BARCODE_HIBC_DM,
    BARCODE_HIBC_QR,
    BARCODE_HIBC_PDF,
    BARCODE_HIBC_MICPDF,
    BARCODE_HIBC_BLOCKF,
    BARCODE_HIBC_AZTEC,
    BARCODE_AZRUNE,
    BARCODE_CODE32,
    BARCODE_EANX_CC,
    BARCODE_EAN128_CC,
    BARCODE_RSS14_CC,
    BARCODE_RSS_LTD_CC,
    BARCODE_RSS_EXP_CC,
    BARCODE_UPCA_CC,
    BARCODE_UPCE_CC,
    BARCODE_RSS14STACK_CC,
    BARCODE_RSS14_OMNI_CC,
    BARCODE_RSS_EXPSTACK_CC,
    BARCODE_CHANNEL,
    BARCODE_CODEONE,
    BARCODE_GRIDMATRIX,
    BARCODE_DOTCODE,
    BARCODE_HANXIN,
    0};


/* Version information */
static char version_string[] = VERSION;
/* Help text */
static char help_message[] = "zint tcl(stub,obj) dll\n"
    "(c) 2014-06-16 ELMICRON GmbH by Harald Oehlmann\n"
    " Generate barcode in tk images and in file output\n"
    "Usage:\n"
    " zint encode option value...\n"
    "  Available options:\n"
    "   -bind bool: bars above/below the code, size set by -border\n"
    "   -box bool: box around bar code, size set be -border\n"
    "   -barcode choice: symbology, use 'zint symbology' to get a list\n"
    "   -height integer: Symbol height in modules\n"
    "   -whitesp integer: horizontal quiet zone in modules\n"
    "   -border integer: with of a border around the symbol. Use with -bind/-box 1\n"
    "   -fg color: set foreground color as 6 hex rrggbb\n"
    "   -bg color: set background color as 6 hex rrggbb\n"
    "   -cols integer: PDF417, Codablock F: number of columns\n"
    "   -rows integer: Codablock F: number of rows\n"
    "   -vers integer: Symbology option, QR-Code, Plessy\n"
    "   -rotate angle: Image rotation by 0,90 or 270 degrees\n"
    "   -secure integer: EC Level (PDF417, QR)\n"
    "   -mode: Structured primary data mode (Maxicode, Composite)\n"
    "   -primary text: Structured primary data (Maxicode, Composite)\n"
    "   -scale double: Scale the image to this factor\n"
    "   -format binary|unicode|gs1: input data format. Default:unicode"
    "   -notext bool: no interpretation line\n"
    "   -square bool: force Data Matrix symbols to be square\n"
    "   -init bool: Create reader initialisation symbol (Code 128, Data Matrix)\n"
    "   -smalltext bool: tiny interpretation line font\n"
    "   -to {x0 y0 ?width? ?height?}: place to put in photo image\n"
    "\n"
    "zint symbologies: List available symbologies\n"
    " zint help\n"
    " zint version\n"
    ;

/*----------------------------------------------------------------------------*/
/* Exported symbols */
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
EXPORT BOOL WINAPI DllEntryPoint (HINSTANCE hInstance,
    DWORD seginfo, LPVOID lpCmdLine)
{
  /* Don't do anything, so just return true */
  return TRUE;
}
#endif
/*----------------------------------------------------------------------------*/
/* Initialisation Procedures */
EXPORT int Zint_Init (Tcl_Interp *Interp)
{
    /*------------------------------------------------------------------------*/
#ifdef USE_TCL_STUBS
    if (Tcl_InitStubs(Interp, "8.1", 0) == NULL)
#else
    if (Tcl_PkgRequire(Interp, "Tcl", "8.1", 0) == NULL)
#endif
    {
        return TCL_ERROR;
    }
    /*------------------------------------------------------------------------*/
#ifdef USE_TK_STUBS
    if (Tk_InitStubs(Interp, "8.1", 0) == NULL)
#else
    if (Tcl_PkgRequire(Interp, "Tk", "8.1", 0) == NULL)
#endif
    {
        return TCL_ERROR;
    }
    /*------------------------------------------------------------------------*/
    Tcl_CreateObjCommand(Interp, "zint", Zint, (ClientData)NULL,
        (Tcl_CmdDeleteProc *)NULL);
    Tcl_PkgProvide (Interp, "zint", version_string);
    /*------------------------------------------------------------------------*/
    return TCL_OK;
}
/*----------------------------------------------------------------------------*/
/* >>>>> Called routine */
/*----------------------------------------------------------------------------*/
/* Decode tcl commands */
static int Zint(ClientData unused, Tcl_Interp *interp, int objc,
    Tcl_Obj *CONST objv[])
{
    /* Option list and indexes */
    char *subCmds[] = {"encode", "symbologies", "version", "help", NULL};
    enum iCommand {iEncode, iSymbologies, iVersion, iHelp};
    /* choice of option */
    int Index;
    /*------------------------------------------------------------------------*/
    /* > Check if option argument is given and decode it */
    if (objc > 1)
    {
        if(Tcl_GetIndexFromObj(interp, objv[1], (const char **) subCmds,
            "option", 0, &Index)
            == TCL_ERROR)
        {
            return TCL_ERROR;
        }
    } else {
        Tcl_WrongNumArgs(interp, 1, objv, "option");
        return TCL_ERROR;
    }
    /*------------------------------------------------------------------------*/
    /* > Call functions in dependency of Index */
    /*------------------------------------------------------------------------*/
    switch (Index)
    {
    case iEncode:
        return Encode(interp, objc, objv);
    case iSymbologies:
        {
            Tcl_Obj *oRes;
            int posCur;
            oRes = Tcl_NewObj();
            for (posCur = 0 ; s_code_list[posCur] != NULL; posCur++) {
                if( ZBarcode_ValidID(s_code_number[posCur]) != 0) {
                    if (TCL_OK != Tcl_ListObjAppendElement(interp,
                        oRes, Tcl_NewStringObj(s_code_list[posCur],-1)))
                    {
                        return TCL_ERROR;
                    }
                }
            }
            Tcl_SetObjResult(interp,oRes);
            return TCL_OK;
        }
    case iVersion:
        Tcl_SetObjResult(interp,
            Tcl_NewStringObj(version_string, -1));
        return TCL_OK;
    case iHelp:
    default:
        Tcl_SetObjResult(interp,
            Tcl_NewStringObj(help_message, -1));
        return TCL_OK;
    }
}
/*----------------------------------------------------------------------------*/
/* >>>>> Encode */
/*----------------------------------------------------------------------------*/
/* Encode image */
static int Encode(Tcl_Interp *interp, int objc,
    Tcl_Obj *CONST objv[])
{
    struct zint_symbol *hSymbol;
    Tcl_DString dsInput;
    char *pStr = NULL;
    int lStr;
    Tcl_Encoding hUTF8Encoding;
    int rotate_angle=0;
    int fError = 0;
    Tcl_DString dString;
    int optionPos;
    int destX0 = 0;
    int destY0 = 0;
    int destWidth = 0;
    int destHeight = 0;
    /*------------------------------------------------------------------------*/
    /* >> Check if at least data and object is given and a pair number of */
    /* >> options */
    if ( objc < 4 || (objc % 2) != 0 )
    {
        Tcl_WrongNumArgs(interp, 2, objv, "data photo ?-switch value?...");
        return TCL_ERROR;
    }
    /*------------------------------------------------------------------------*/
    /* >>> Prepare encoding */
    hUTF8Encoding = Tcl_GetEncoding(interp, "utf-8");
    if (NULL == hUTF8Encoding) {
        return TCL_ERROR;
    }
    /*------------------------------------------------------------------------*/
    /* >>> Prepare zint object */
    hSymbol = ZBarcode_Create();
    hSymbol->input_mode = UNICODE_MODE;
    /*------------------------------------------------------------------------*/
    /* >> Decode options */
    for (optionPos = 4; optionPos < objc; optionPos+=2) {
        /*--------------------------------------------------------------------*/
        /* Option list and indexes */
        char *optionList[] = {
            "-bind", "-box", "-barcode", "-height", "-whitesp", "-border",
            "-fg", "-bg", "-cols", "-rows", "-vers", "-rotate",
            "-secure", "-mode", "-primary", "-scale", "-format",
            "-notext", "-square", "-dmre", "-init", "-smalltext", "-to",
            NULL};
        enum iOption {
            iBind, iBox, iBarcode, iHeight, iWhiteSp, iBorder,
            iFG, iBG, iCols, iRows, iVers, iRotate,
            iSecure, iMode, iPrimary, iScale, iFormat,
            iNoText, iSquare, iDMRE, iInit, iSmallText, iTo
            };
        int optionIndex;
        int intValue;
        double doubleValue;
        /*--------------------------------------------------------------------*/
        if(Tcl_GetIndexFromObj(interp, objv[optionPos],
            (const char **) optionList,
            "zint option", optionPos-1, &optionIndex)
            == TCL_ERROR)
        {
            fError = 1;
            break;
        }
        /*--------------------------------------------------------------------*/
        /* >> Decode object */
        switch (optionIndex) {
        case iBind:
        case iBox:
        case iInit:
        case iSmallText:
        case iNoText:
        case iSquare:
        case iDMRE:
            /* >> Binary options */
            if (TCL_OK != Tcl_GetBooleanFromObj(interp, objv[optionPos+1],
                    &intValue))
            {
                fError = 1;
            }
            break;
        case iFG:
        case iBG:
            /* >> Colors */
            pStr = Tcl_GetStringFromObj(objv[optionPos+1],&lStr);
            if (lStr != 6) {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("Color is not 6 hex",-1));
                fError = 1;
            }
            break;
        case iScale:
            /* >> Float */
            if (TCL_OK != Tcl_GetDoubleFromObj(interp, objv[optionPos+1],
                &doubleValue))
            {
                fError = 1;
            }
            break;
        case iBorder:
        case iHeight:
        case iCols:
        case iRows:
        case iVers:
        case iSecure:
        case iMode:
        case iRotate:
        case iWhiteSp:
            /* >> Int */
            if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1],
                    &intValue))
            {
                fError = 1;
            }
            break;
        case iPrimary:
            /* > Primary String up to 90 characters */
            /* > Output filename up to 250 characters */
            Tcl_DStringInit(& dString);
            pStr = Tcl_GetStringFromObj(objv[optionPos+1], &lStr);
            Tcl_UtfToExternalDString( hUTF8Encoding, pStr, lStr, &dString);
            if (Tcl_DStringLength(&dString) > (optionIndex==iPrimary?90:250)) {
                Tcl_DStringFree(&dString);
                Tcl_SetObjResult(interp,Tcl_NewStringObj("String to long", -1));
                fError = 1;
            }
            break;
        }
        if (fError) {
            break;
        }
        /*--------------------------------------------------------------------*/
        switch (optionIndex) {
        case iBind:
            if (intValue) {
                hSymbol->output_options |= BARCODE_BIND;
            } else {
                hSymbol->output_options &= ~BARCODE_BIND;
            }
            break;
        case iBox:
            if (intValue) {
                hSymbol->output_options |= BARCODE_BOX;
            } else {
                hSymbol->output_options &= ~BARCODE_BOX;
            }
            break;
        case iInit:
            if (intValue) {
                hSymbol->output_options |= READER_INIT;
            } else {
                hSymbol->output_options &= ~READER_INIT;
            }
            break;
        case iSmallText:
            if (intValue) {
                hSymbol->output_options |= SMALL_TEXT;
            } else {
                hSymbol->output_options &= ~SMALL_TEXT;
            }
            break;
        case iFG:
            strncpy(hSymbol->fgcolour, pStr, 6);
            hSymbol->fgcolour[6]='\0';
            break;
        case iBG:
            strncpy(hSymbol->bgcolour, pStr, 6);
            hSymbol->bgcolour[6]='\0';
            break;
        case iNoText:
            hSymbol->show_hrt = (intValue?0:1);
            break;
        case iSquare:
            hSymbol->option_3 = (intValue?DM_SQUARE:0);
            break;
        case iDMRE:
            /* DM_SQUARE overwrites DM_DMRE */
            if (hSymbol->option_3 != DM_DMRE) {
                hSymbol->option_3 = (intValue?DM_DMRE:0);
            }
            break;
        case iScale:
            if (doubleValue < 0.01) {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("Scale below 0.01", -1));
                fError = 1;
            } else {
                hSymbol->scale = (float)doubleValue;
            }
            break;
        case iBorder:
            if (intValue < 0 || intValue > 1000) {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("Border out of range", -1));
                fError = 1;
            } else {
                hSymbol->border_width = intValue;
            }
            break;
        case iHeight:
            if (intValue < 1 || intValue > 1000) {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("Height out of range", -1));
                fError = 1;
            } else {
                hSymbol->height = intValue;
            }
            break;
        case iCols:
        case iVers:
            /* >> Int in Option 2 */
            if (intValue < 1
                || (optionIndex==iCols && intValue > 66)
                || (optionIndex==iVers && intValue > 47))
            {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("cols/vers out of range", -1));
                fError = 1;
            } else {
                hSymbol->option_2 = intValue;
            }
            break;
        case iSecure:
        case iMode:
        case iRows:
            /* >> Int in Option 1 */
            if ( (optionIndex==iSecure && (intValue < 1 || intValue > 8))
                || (optionIndex==iMode && (intValue < 0 || intValue > 6))
                || (optionIndex==iRows && (intValue < 0 || intValue > 44)))
            {
                Tcl_SetObjResult(interp,
                    Tcl_NewStringObj("secure/mode/rows out of range", -1));
                fError = 1;
            } else {
                hSymbol->option_1 = intValue;
            }
            break;
        case iPrimary:
            strcpy(hSymbol->primary, Tcl_DStringValue( &dString ) );
            Tcl_DStringFree(&dString);
            break;
        case iRotate:
            /* >> Rotate angle */
            /*----------------------------------------------------------------*/
            {
                char *rotateList[] = {"0", "90", "180", "270", "360", NULL};
                enum iRotate { iRotate0, iRotate90, iRotate180, iRotate270 };
                /*------------------------------------------------------------*/
                if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                    (const char **) rotateList,
                    "rotate", optionPos, &intValue)
                    == TCL_ERROR)
                {
                    fError = 1;
                    break;
                }
                switch (intValue) {
                    case iRotate90: rotate_angle = 90; break;
                    case iRotate180: rotate_angle = 180; break;
                    case iRotate270: rotate_angle = 270; break;
                    default: rotate_angle = 0; break;
                }
            }
            break;
        case iBarcode:
            if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                (const char **) s_code_list,"-barcode", optionPos, &intValue)
                == TCL_ERROR)
            {
                fError = 1;
            } else {
                hSymbol->symbology = s_code_number[intValue];
            }
            break;
        case iWhiteSp:
            hSymbol->whitespace_width = intValue;
            break;
        case iTo:
            /* >> Decode the -to parameter as list of X0 Y0 ?Width Height? */
            {
                Tcl_Obj *poParam;
                if (TCL_OK != Tcl_ListObjLength(interp,
                    objv[optionPos+1], &lStr))
                {
                    fError = 1;
                } else if ( ! ( lStr == 2 || lStr == 4 ) ) {
                    Tcl_SetObjResult(interp,
                        Tcl_NewStringObj(
                        "option -to not a list of 2 or 4", -1));
                    fError = 1;
                } else if ((
                    TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                        0, &poParam)
                    || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destX0)
                    || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                        1, &poParam)
                    || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destY0)
                    || lStr == 4) && (
                    TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                        2, &poParam)
                    || TCL_OK != Tcl_GetIntFromObj(interp,poParam,
                        &destWidth)
                    || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
                        3, &poParam)
                    || TCL_OK != Tcl_GetIntFromObj(interp,poParam,
                        &destHeight)
                    ))
                {
                    fError = 1;

                }
            }
            break;
        case iFormat:
            /* >> Format of the input data */
            /*----------------------------------------------------------------*/
            {
                char *formatList[] = {"binary", "gs1", "unicode",NULL};
                enum iFormat { iBinary, iGS1, iUnicode };
                /*------------------------------------------------------------*/
                if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
                    (const char **) formatList,
                    "format", optionPos, &intValue)
                    == TCL_ERROR)
                {
                    fError = 1;
                    break;
                }
                switch (intValue) {
                    case iBinary: hSymbol->input_mode = DATA_MODE; break;
                    case iGS1: hSymbol->input_mode = GS1_MODE; break;
                    default: hSymbol->input_mode = UNICODE_MODE; break;
                }
            }
        }
    }
    /*------------------------------------------------------------------------*/
    /* >>> Prepare input dstring */
    Tcl_DStringInit(& dsInput);
    /*------------------------------------------------------------------------*/
    if (!fError) {
        /*--------------------------------------------------------------------*/
        /* >>> Do output */
        Tk_PhotoHandle hPhoto;
        /*--------------------------------------------------------------------*/
        /* >>> Get input - 2nd argument */
        if (hSymbol->input_mode == DATA_MODE) {
            /* Binary data */
            pStr = (char *) Tcl_GetByteArrayFromObj(objv[2], &lStr);
        } else {
            /* UTF8 Data */
            pStr = Tcl_GetStringFromObj(objv[2], &lStr);
            Tcl_UtfToExternalDString( hUTF8Encoding, pStr, lStr, &dsInput);
            pStr = Tcl_DStringValue( &dsInput );
            lStr = Tcl_DStringLength( &dsInput );
        }
        /*--------------------------------------------------------------------*/
        if( 0 != ZBarcode_Encode_and_Buffer(hSymbol,
            (unsigned char *) pStr, lStr, rotate_angle) )
        {
            /* >> Encode error */
            fError = 1;
            Tcl_SetObjResult(interp, Tcl_NewStringObj(hSymbol->errtxt, -1));
        } else if (
            NULL == (hPhoto = Tk_FindPhoto(interp, Tcl_GetString(objv[3]))))
        {
            Tcl_SetObjResult(interp,
                Tcl_NewStringObj("Unknown photo image", -1));
            fError = 1;
        } else {
            Tk_PhotoImageBlock sImageBlock;
            sImageBlock.pixelPtr = (unsigned char *) hSymbol->bitmap;
            sImageBlock.width = hSymbol->bitmap_width;
            sImageBlock.height = hSymbol->bitmap_height;
            sImageBlock.pitch = 3*hSymbol->bitmap_width;
            sImageBlock.pixelSize = 3;
            sImageBlock.offset[0] = 0;
            sImageBlock.offset[1] = 1;
            sImageBlock.offset[2] = 2;
            sImageBlock.offset[3] = 0;
            if (0 == destWidth) {
                destWidth = hSymbol->bitmap_width;
            }
            if (0 == destHeight) {
                destHeight = hSymbol->bitmap_height;
            }
            if (TCL_OK != Tk_PhotoPutBlock(interp, hPhoto, &sImageBlock,
                destX0, destY0, destWidth, destHeight,
                TK_PHOTO_COMPOSITE_OVERLAY))
            {
                fError = 1;
            }
        }
    }
    /*------------------------------------------------------------------------*/
    Tcl_FreeEncoding(hUTF8Encoding);
    Tcl_DStringFree(& dsInput);
    ZBarcode_Delete(hSymbol);
    /*------------------------------------------------------------------------*/
    if (fError) {
        return TCL_ERROR;
    }
    return TCL_OK;
}
Changes to jni/zint/backend_tcl/zint_tcl.dsp.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\backend" /I "C:\Program Files\tcl8.5\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /D "NO_PNG" /YX /FD /D ZINT_VERSION="\"2.5.0\"" /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  tclstub85.lib tkstub85.lib /nologo /dll /machine:I386 /out:"zint.dll" /libpath:"C:\Program Files\tcl8.5\lib"

!ELSEIF  "$(CFG)" == "zint_tcl - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\backend" /I "C:\Program Files\tcl8.5\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /D "NO_PNG" /YX /FD /GZ /D ZINT_VERSION="\"2.5.0\"" /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib tclstub85.lib tkstub85.lib /nologo /dll /debug /machine:I386 /out:"Debug/zint.dll" /pdbtype:sept /libpath:"C:\Program Files\tcl8.5\lib"

!ENDIF 

# Begin Target

# Name "zint_tcl - Win32 Release"
# Name "zint_tcl - Win32 Debug"







|









|















|









|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\backend" /I "C:\myprograms\tcl8.5\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /D "NO_PNG" /YX /FD /D ZINT_VERSION="\"2.5.2\"" /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib tclstub85.lib tkstub85.lib /nologo /dll /machine:I386 /out:"zint.dll" /libpath:"C:\myprograms\tcl8.5\lib"

!ELSEIF  "$(CFG)" == "zint_tcl - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\backend" /I "C:\myprograms\tcl8.5\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZINT_TCL_EXPORTS" /D "NO_PNG" /FR /YX /FD /GZ /D ZINT_VERSION="\"2.5.0\"" /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib tclstub85.lib tkstub85.lib /nologo /dll /debug /machine:I386 /out:"Debug/zint.dll" /pdbtype:sept /libpath:"C:\myprograms\tcl8.5\lib"

!ENDIF 

# Begin Target

# Name "zint_tcl - Win32 Release"
# Name "zint_tcl - Win32 Debug"
99
100
101
102
103
104
105








106
107
108
109
110
111
112
SOURCE=..\backend\auspost.c
# End Source File
# Begin Source File

SOURCE=..\backend\aztec.c
# End Source File
# Begin Source File









SOURCE=..\backend\code.c
# End Source File
# Begin Source File

SOURCE=..\backend\code1.c
# End Source File







>
>
>
>
>
>
>
>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
SOURCE=..\backend\auspost.c
# End Source File
# Begin Source File

SOURCE=..\backend\aztec.c
# End Source File
# Begin Source File

SOURCE=..\backend\bmp.c
# End Source File
# Begin Source File

SOURCE=..\backend\codablock.c
# End Source File
# Begin Source File

SOURCE=..\backend\code.c
# End Source File
# Begin Source File

SOURCE=..\backend\code1.c
# End Source File
131
132
133
134
135
136
137












138
139
140
141
142
143
144
145




146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165




166
167
168
169
170
171
172
SOURCE=..\backend\composite.c
# End Source File
# Begin Source File

SOURCE=..\backend\dmatrix.c
# End Source File
# Begin Source File













SOURCE=..\backend\gridmtx.c
# End Source File
# Begin Source File

SOURCE=..\backend\gs1.c
# End Source File
# Begin Source File





SOURCE=..\backend\imail.c
# End Source File
# Begin Source File

SOURCE=..\backend\large.c
# End Source File
# Begin Source File

SOURCE=..\backend\library.c
# End Source File
# Begin Source File

SOURCE=..\backend\maxicode.c
# End Source File
# Begin Source File

SOURCE=..\backend\medical.c
# End Source File
# Begin Source File





SOURCE=..\backend\pdf417.c
# End Source File
# Begin Source File

SOURCE=..\backend\plessey.c
# End Source File







>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>




















>
>
>
>







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
SOURCE=..\backend\composite.c
# End Source File
# Begin Source File

SOURCE=..\backend\dmatrix.c
# End Source File
# Begin Source File

SOURCE=..\backend\dotcode.c
# End Source File
# Begin Source File

SOURCE=..\backend\eci.c
# End Source File
# Begin Source File

SOURCE=..\backend\gif.c
# End Source File
# Begin Source File

SOURCE=..\backend\gridmtx.c
# End Source File
# Begin Source File

SOURCE=..\backend\gs1.c
# End Source File
# Begin Source File

SOURCE=..\backend\hanxin.c
# End Source File
# Begin Source File

SOURCE=..\backend\imail.c
# End Source File
# Begin Source File

SOURCE=..\backend\large.c
# End Source File
# Begin Source File

SOURCE=..\backend\library.c
# End Source File
# Begin Source File

SOURCE=..\backend\maxicode.c
# End Source File
# Begin Source File

SOURCE=..\backend\medical.c
# End Source File
# Begin Source File

SOURCE=..\backend\pcx.c
# End Source File
# Begin Source File

SOURCE=..\backend\pdf417.c
# End Source File
# Begin Source File

SOURCE=..\backend\plessey.c
# End Source File
183
184
185
186
187
188
189




190
191
192
193
194
195
196
SOURCE=..\backend\ps.c
# End Source File
# Begin Source File

SOURCE=..\backend\qr.c
# End Source File
# Begin Source File





SOURCE=..\backend\reedsol.c
# End Source File
# Begin Source File

SOURCE=..\backend\render.c
# End Source File







>
>
>
>







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
SOURCE=..\backend\ps.c
# End Source File
# Begin Source File

SOURCE=..\backend\qr.c
# End Source File
# Begin Source File

SOURCE=..\backend\raster.c
# End Source File
# Begin Source File

SOURCE=..\backend\reedsol.c
# End Source File
# Begin Source File

SOURCE=..\backend\render.c
# End Source File
Deleted jni/zint/docs/README.
1
2
3
Documentation has now been removed from the Zint package in
preference of the online documentation at:
http://www.zint.org.uk
<
<
<






Added jni/zint/docs/manual.txt.






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
*******************************************************************************
* For reference the following is a text-only version of the Zint manual.      *
* The full version can be accessed at http://zint.org.uk/Manual.aspx          *
*******************************************************************************

Zint Barcode Generator and Zint Barcode Studio User Manual
==========================================================

1. Introduction
===============
The Zint project aims to provide a complete cross-platform open source barcode
generating solution. The package currently consists of a Qt based GUI, a 
command line executable and a library with an API to allow developers access to 
the capabilities of Zint. It is hoped that Zint provides a solution which is 
flexible enough for professional users while at the same time takes care of as 
much of the processing as possible to allow easy translation from input data to 
barcode image. 

The library which forms the main component of the Zint project is currently 
able to encode data in over 50 barcode symbologies (types of barcode), for each 
of which it is possible to translate that data from either Unicode (UTF-8) or a 
raw 8-bit data stream. The image can be rendered as either a Portable Network 
Graphic (PNG) image, Windows Bitmap (BMP), Graphics Interchange Format (GIF), 
ZSoft Paintbrush image (PCX), as Encapsulated Post Script (EPS) or as a 
Scalable Vector Graphic (SVG). Many options are available for setting the 
characteristics of the output image including the size and colour of the image, 
the amount of error correction used in the symbol and, in the case of raster 
images, the orientation of the image. 

1.1 Terms of Reference
----------------------
Some of the words and phrases used in this document are specific to barcoding,
and so a brief explanation is given to help understanding:

symbol: A symbol is an image which encodes data according to one of the
        standards. This encompases barcodes (linear symbols) as well as any of
        the other methods of representing data used in this program.
        
symbology: A method of encoding data to create a certain type of symbol.

linear: A linear symbol is one which consists of bars and spaces, and is what
        most people associate with the term "barcode". Examples include EAN.
        
stacked: A stacked symbol consists of multiple linear symbols placed one above
        another and which together hold the message, usually allong side some
        error correction data. Examples include PDF417.
        
matrix: A matrix symbol is one based on a (usually square) grid of elements.
        Examples include Data Matrix, but Maxicode and DotCode are also
        considered matrix symbologies.
        
x-dimension: The x-dimension of a symbol is size (usually the width) of the
        smallest element. For a linear symbology this is the width of the
        smallest bar. The default size of the x-dimension in a raster image
        is 2 pixels. Many symbologies have a fixed width-to-height ratio where
        the height is expressed as a multiple of the x-dimension.
        
composite: A composite symbology is one which is made up of elements which are
        both linear and stacked. Those currently supported are made up of a
        linear "primary" message above which is printed a stacked component
        based on the PDF417 symbology. These symbols also have a separator
        which seperates the linear and the stacked components.
        
GS-1 data: This is a structured way of representing information which consists
        of "chunks" of data, each of which starts with an Application
        Identifier. The AI identifies what type of information is being
        encoded. See Appendix C.
        
Reader Initialisation: Some symbologies allow a special character to be included
        which can be detected by the scanning equipment as signifying that the
        data is used to program or change settings in that equipment. This data
        is usually not passed on to the software which handles normal input
        data. This feature should only be used if you are familiar with the
        programming codes relevant to your scanner.
        
ECI:    The ECI mechanism allows for multi-language data to be encoded in
        symbols which would usually support only Latin-1 characters. This can
        be useful, for example, if you need to encode cyrillic characters, but
        should be used with caution as not all scanners support this method.

2. Installing Zint
==================

2.1 Linux
---------
The easiest way to configure compilation is to take advantage of the CMake 
utilities. You will need to install CMake and libpng first. Note that you will 
need both libpng and libpng-devel packages. If you want to take advantage of 
Zint Barcode Studio you will also need the Qt libraries pre-installed.

Once you have fulfilled these requirements unzip the source code tarball and 
follow these steps in the top directory:

mkdir build
cd build
cmake ..
make
make install

The command line program can be accessed by typing

zint {options} -d {data}

Notice that the data needs to be entered after all other options. Any options 
given after the data will be ignored. The GUI can be accessed by typing

zint-qt

To test that the installation has been successful a shell script is included in 
the /frontend folder. To run the test type

./test.sh

This should create numerous files showing the many modes of operation which are 
available from Zint.

2.2 Microsoft Windows
---------------------
To run Zint Barcode Studio on Windows simply download and run the installation 
executable and follow the instructions on-screen.

2.3 Apple macOS
---------------
Zint can be compiled on macOS from the command line using the same steps as shown 
for Linux above. Currently the Zint Barcode Studio GUI is not known to work on 
macOS. The Zint developers do not currently have access to Apple hardware and
so are not able to provide support or binaries for macOS. If you are a macOS
developer, however, or if you have any success in building Zint on macOS, we
would love to hear from you.

2.4 zint tcl backend
--------------------
The tcl backend may be build using the provided TEA build on Linux, Windows,
Mac-OS and Android. For Windows, a MS-VC6 makefile is also available.

3. Using Zint Barcode Studio
============================
Zint Barcode Studio is the graphical user interface for Zint. If you are
starting from a command line interface you can start the GUI by typing

zint-qt

or in Windows

zint-qt.exe


(The rest of this section of the manual involves use of the GUI, so has been
removed from this text-only version)


4. Using the Command Line
=========================
This section describes how to encode data using the command line front end 
program. The examples given are for the Linux platform, but the same options
are available for Windows - just rememer to include the executable file
extension. i.e.:

zint.exe -d "This Text"


4.1 Inputting data
------------------
The data to encode can be entered at the command line using the -d option, for 
example 

zint -d "This Text"

This will encode the text "This Text". Zint will use the default symbology, 
Code 128, and output to the default file out.png in the current directory. 
Alternatively, if libpng was not present when Zint was built, the default
output file will be out.gif. The -d switch and the input data should always
be the last entry on the command line input. Any options given after this
will be ignored. 

The data input to Zint is assumed to be encoded in Unicode (UTF-8) format. If 
you are encoding characters beyond the 7-bit ASCII set using a scheme other than 
Unicode then you will need to set the appropriate input options as shown in 
section 4.11 below. 

Non-printing characters can be entered on the command line using the backslash 
(\) as an escape character. Permissible characters are shown in the table 
below. Note that this only applies on the command line. 

-------------------------------------------------------------
Escape Character  |  ASCII Equivalent  |  Interpretation
-------------------------------------------------------------
\0                |  0x00              |  Null
\E                |  0x04              |  End of Transmission
\a                |  0x07              |  Bell
\b                |  0x08              |  Backspace
\t                |  0x09              |  Horizontal Tab
\n                |  0x0A              |  Line Feed
\v                |  0x0B              |  Vertical Tab
\f                |  0x0C              |  Form Feed
\r                |  0x0D              |  Carriage Return
\e                |  0x1B              |  Escape
\G                |  0x1D              |  Group Selector
\R                |  0x1E              |  Record Selector
-------------------------------------------------------------

Input data can be read directly from file using the -i switch as shown below. 
The input file is assumed to be Unicode (UTF-8) formatted unless an alternative 
mode is selected. This command replaces the use of the -d switch and should
similarly be the last option given.

zint -i ./somefile.txt

4.2 Directing Output
--------------------
Output can be directed to a file other than the default using the -o switch. 
For example:

zint -o here.png -d "This Text"

This draws a Code 128 barcode in the file here.png. If an encapsulated Post Script 
file is needed simply append the file name with .eps, and so on for the other
supported file types:

zint -o there.eps -d "This Text"

4.3 Selecting barcode type
--------------------------
Selecting which type of barcode you wish to produce (i.e. which symbology to 
use) can be done at the command line using the -b or --barcode= switch followed 
by the appropriate integer value in the following table. For example to create
a Data Matrix symbol you could use:

zint -o datamatrix.png -b 71 -d "Data to encode"

--------------------------------------------------------------------------------
Numeric Value  |  Barcode Name
--------------------------------------------------------------------------------
1              |  Code 11
2              |  Standard Code 2 of 5
3              |  Interleaved 2 of 5
4              |  Code 2 of 5 IATA
6              |  Code 2 of 5 Data Logic
7              |  Code 2 of 5 Industrial
8              |  Code 3 of 9 (Code 39)
9              |  Extended Code 3 of 9 (Code 39+)
13             |  EAN (Including EAN-8 and EAN-13)
14             |  EAN + Check Digit
16             |  GS1-128 (UCC.EAN-128)
18             |  Codabar
20             |  Code 128 (automatic subset switching)
21             |  Deutshe Post Leitcode
22             |  Deutshe Post Identcode
23             |  Code 16K
24             |  Code 49
25             |  Code 93
28             |  Flattermarken
29             |  GS1 DataBar-14
30             |  GS1 DataBar Limited
31             |  GS1 DataBar Extended
32             |  Telepen Alpha
34             |  UPC A
35             |  UPC A + Check Digit
37             |  UPC E
38             |  UPC E + Check Digit
40             |  PostNet
47             |  MSI Plessey
49             |  FIM
50             |  LOGMARS
51             |  Pharmacode One-Track
52             |  PZN
53             |  Pharmacode Two-Track
55             |  PDF417
56             |  PDF417 Truncated
57             |  Maxicode
58             |  QR Code
60             |  Code 128 (Subset B)
63             |  Australia Post Standard Customer
66             |  Australia Post Reply Paid
67             |  Australia Post Routing
68             |  Australia Post Redirection
69             |  ISBN (EAN-13 with verification stage)
70             |  Royal Mail 4 State (RM4SCC)
71             |  Data Matrix (ECC200)
72             |  EAN-14
74             |  Codablock-F
75             |  NVE-18
76             |  Japanese Postal Code
77             |  Korea Post
79             |  GS1 DataBar-14 Stacked
80             |  GS1 DataBar-14 Stacked Omnidirectional
81             |  GS1 DataBar Expanded Stacked
82             |  PLANET
84             |  MicroPDF417
85             |  USPS OneCode
86             |  Plessey Code
87             |  Telepen Numeric
89             |  ITF-14
90             |  Dutch Post KIX Code
92             |  Aztec Code
93             |  DAFT Code
97             |  Micro QR Code
98             |  HIBC Code 128
99             |  HIBC Code 39
102            |  HIBC Data Matrix ECC200
104            |  HIBC QR Code
106            |  HIBC PDF417
108            |  HIBC MicroPDF417
112            |  HIBC Aztec Code
115            |  DotCode
116            |  Han Xin (Chinese Sensible) Code
128            |  Aztec Runes
129            |  Code 32
130            |  Composite Symbol with EAN linear component
131            |  Composite Symbol with GS1-128 linear component
132            |  Composite Symbol with GS1 DataBar-14 linear component
133            |  Composite Symbol with GS1 DataBar Limited component
134            |  Composite Symbol with GS1 DataBar Extended component
135            |  Composite Symbol with UPC A linear component
136            |  Composite Symbol with UPC E linear component
137            |  Composite Symbol with GS1 DataBar-14 Stacked component
138            |  Composite Symbol with GS1 DataBar-14 Stacked Omnidirectional 
               |     component
139            |  Composite Symbol with GS1 DataBar Expanded Stacked component
140            |  Channel Code
141            |  Code One
142            |  Grid Matrix
--------------------------------------------------------------------------------

4.4 Adjusting height
--------------------
The height of a linear symbol can be adjusted using the --height switch. For 
example:

zint --height=100 -d "This Text"

This specifies a symbol height of 100 times the x-resolution of the symbol.

4.5 Adjusting whitespace
------------------------
The amount of whitespace to the left and right of the generated barcode can be 
altered using the –w switch. For example:

zint -w 10 -d "This Text"

This specifies a whitespace width of 10 times the x-resolution of the symbol.

4.6 Adding boundary bars and boxes
----------------------------------
Zint allows the symbol to be bound with 'boundary bars' using the option 
--bind. These bars help to prevent misreading of the symbol by corrupting a 
scan if the scanning beam strays off the top or bottom of the symbol. Zint can 
also put a border right around the symbol and its whitespace with the --box 
option. This option is automatically selected for ITF-14 symbols.

The width of the boundary or box can be specified using the --border switch. 
For example:

zint --box --border=10 -d "This"

gives a box with a width 10 times the x-resolution of the symbol.

4.7 Using colour
----------------
The default colours of a symbol are a black symbol on a white background. Zint 
allows you to change this. The -r switch allows the default colours to be 
inverted so that a white symbol is shown on a black background. For example the 
command

zint -r -d "This"

gives an inverted Code 128 symbol. This is not practical for most symbologies 
but white-on-black is allowed by the Data Matrix ECC200 and Aztec Code 
symbology specifications.

For more specific needs the foreground (ink) and background (paper) colours
can be specified using the --fg= and --bg= options followed by a number in RRGGBB
hexadecimal notation (the same system used in HTML). For example the command

zint --fg=004700 -d "This"

alters the symbol to a dark green.

4.8 Rotating the Symbol
-----------------------
The symbol can be rotated through four orientations using the --rotate= option 
followed by the angle of rotation as shown below. This option is only available 
with raster image (PNG, BMP, GIF and PCX) output. 

--rotate=0 (default)
--rotate=90
--rotate=180
--rotate=270

4.9 Adjusting image size
------------------------
The scale of the image can be altered using the --scale= option followed by a 
multiple of the default x-dimension. The default x-dimension is 2 pixels. For
example for PNG images a scale of 5 will increase the x-dimension to 10 pixels. 

4.10 Input modes
----------------
By default all input data is assumed to be encoded in Unicode (UTF-8) format. 
Many barcode symbologies encode data using Latin-1 (ISO-8851-1) character 
encoding, so input is converted from Unicode to Latin-1 before being put in the 
symbol. In addition QR Code, Micro QR Code, Han Xin Code and Grid Matrix 
standards can encode Chinese or Japanese characters which are also converted 
from Unicode. If Zint encounters characters which can not be encoded using the 
default character encoding then it will take advantage of the ECI (Extended 
Channel Interpretations) mechanism to encode the data. Be aware that not all 
barcode readers support ECI mode, so this can sometimes lead to unreadable 
barcodes. If you are using characters beyond those supported by Latin-1 then 
you should check that the resulting barcode can be understood by your target 
barcode reader. Zint will generate a warning message when ECI codes have been
inserted into a symbol.

GS1 data can be encoded in a number of symbologies. Application identifiers
should be enclosed in [square brackets] followed by the data to be encoded (see 
5.1.12.3). To encode GS1 data use the --gs1 option. GS1 mode is assumed (and 
doesn't need to be set) for EAN-128, DataBar and Composite symbologies but is 
also available for Code 16k, Data Matrix, Aztec Code, DotCode and QR Code. 

HIBC data may also be encoded in the symbologies Code 39, Code128, Codablock-F,
Datamatrix, QR-Code, PDF417 and Aztec-Code. Within this mode, the leading '+' and the
check character is automatically added.

The --binary option prevents Zint from performing any convertion of the data 
before placing in the barcode symbol and should be used if you are encoding raw 
binary or encrypted data.

If your platform does not use Unicode or if you are using data from file which 
is not stored in UTF-8 then you can specify the encoding by using the --binary 
switch in combination with the --eci= switch followed by the appropriate number 
from the table below. This procedure adds an ECI flag in the barcode data which 
tells the barcode reader to change character encoding.

--------------------------------------------------------
ECI Code  |  Character Encoding Scheme
--------------------------------------------------------
3         |  ISO-8859-1 - Latin alphabet No. 1 (default)
4         |  ISO-8859-2 - Latin alphabet No. 2
5         |  ISO-8859-3 - Latin alphabet No. 3
6         |  ISO-8859-4 - Latin alphabet No. 4
7         |  ISO-8859-5 - Latin/Cyrillic alphabet
8         |  ISO-8859-6 - Latin/Arabic alphabet
9         |  ISO-8859-7 - Latin/Greek alphabet
10        |  ISO-8859-8 - Latin/Hebrew alphabet
11        |  ISO-8859-9 - Latin alphabet No. 5
12        |  ISO-8859-10 - Latin alphabet No. 6
13        |  ISO-8859-11 - Latin/Thai alphabet
15        |  ISO-8859-13 - Latin alphabet No. 7
16        |  ISO-8859-14 - Latin alphabet No. 8 (Celtic)
17        |  ISO-8859-15 - Latin alphabet No. 9
18        |  ISO-8859-16 - Latin alphabet No. 10
21        |  Windows-1250 - Latin 2 (Central Europe)
22        |  Windows-1251 - Cyrillic
23        |  Windows-1252 - Latin 1
24        |  Windows-1256 - Arabic
26        |  Unicode (UTF-8)
--------------------------------------------------------

4.11 Batch processing
---------------------
Data can be batch processed by reading from a text file and producing a 
separate barcode image for each line of text in that file. To do this use the 
--batch switch. To select the input file from which to read data use the –i 
option. Zint will automatically detect the end of a line of text (in either 
Unix or Windows formatted text files) and produce a symbol each time it finds 
this. Input files should end with a return character – if this is not present 
then Zint will not encode the last line of text, and will warn you that there 
is a problem.

By default Zint will output numbered filenames starting with 00001.png, 
00002.png etc. To change this behaviour use the –o option in combination with 
--batch using special characters in the output file name as shown in the table 
below: 

---------------------------------------------
Input Character   |  Interpretation
---------------------------------------------
~                 |  Insert a number or '0'
#                 |  Insert a number or space
@                 |  Insert a number or "*"
Any other         |  Insert literally
---------------------------------------------

The following table shows some examples to clarify this method:

--------------------------------------------------------------
Input            |  Filenames Generated
--------------------------------------------------------------
-o file~~~.svg   |  file001.svg, file002.svg, file003.svg
-o @@@@bar.png   |  ***1.png, ***2.png, ***3.png
-o my~~~bar.eps  |  my001.bar.eps, my002.bar.eps, my003bar.eps
-o t@es~t~.png   |  t*es0t1.png, t*es0t2.png, t*es0t3.png
--------------------------------------------------------------

4.12 Direct output
------------------
The finished image files can be output directly to stdout for use as part of
a pipe by using the --direct option. By default --direct will output data
as a PNG image, but this can be altered by supplimenting the --direct option
with a --filetype= option followed by the suffix of the file type required.
For example:

zint -b 84 --direct --filetype=pcx -d "Data to encode"

This command will output the symbol as a PCX file to stdout. The currently
supported output file formats are shown in the following table:

--------------------------------------------------------------
Abbreviation |  File format
--------------------------------------------------------------
BMP          |  Windows Bitmap
EPS          |  Encapsulated PostScript
GIF          |  Graphics Interchange Format
PCX          |  ZSoft Paintbrush image
PNG          |  Portable Network Graphic
SVG          |  Scalable Vector Graphic
TXT          |  Text file (see 4.16)
--------------------------------------------------------------

=============================================================================
CAUTION: Outputting binary files to the command shell without catching that
data in a pipe can have unpredictable results. Use with care!
=============================================================================

4.13 Automatic filenames
------------------------
The --mirror option instructs Zint to use the data to be encoded as an
indicator of the filename to be used. This is particularly useful if you are
processing batch data. For example the input data "1234567" will result in
a file named 1234567.png.

There are restrictions, however, on what characters can be stored in a file
name, so the file name may vary from the data if the data includes non-
printable characters, for example, and may be shortened if the data input is
long.

To set the output file format use the --filetype= option as detailed in
section 4.12.

4.14 Working with dots
----------------------
Matrix codes can be rendered as a series of dots or circles rather than the
normal squares by using the --dotty option. This option is only available for
matrix symbologies, and is automatically selected for DotCode. The size of
the dots can be adjusted using the --dotsize= option followed by the radius
of the dot, where that radius is given as a multiple of the x-dimension.

4.15 Help options
-----------------
There are three help options which give information about how to use the
command line. The -h or --help option will display a list of all of the valid
options available, and also gives the exact version of the software.

The -t or --types option gives the table of symbologies along with the symbol
ID numbers.

The -e or --ecinos option gives a list of the ECI codes supported by Zint.

4.16 Other output options
-------------------------
For linear barcodes the text present in the output image can be removed by 
using the --notext option.

The text can be set to bold using the --bold option, or a smaller font
can be substituted using the --small option. The --bold and --small options
can be used together if required.

Zint can output a representation of the symbol data as a set of hexadecimal
values if asked to output to a text file (*.txt) or if given the option
--filetype=txt. This can be used for test and diagnostic purposes.

The --cmyk option is specific to output in encapsulated PostScript, and
converts the RGB colours used to the CMYK colour space. Setting custom
colours at the command line will still need to be done in RRGGBB format.

Additional options are available which are specific to certain symbologies. 
These may, for example, control the amount of error correction data or the 
size of the symbol. These options are discussed in section 6 of this guide. 

5. Using the API
================
Zint has been written using the C language and currently only has an API for 
use with C language programs. A wrapper is available for Pascal/Delphi 
developers thanks to theunknownones from 
http://theunknownones.googlecode.com/svn/trunk/Components/ZintBarcode/.
This wrapper, however, is likely to be out of date and may not function as
expected.

The libzint API has been designed to be very similar to that used by the GNU 
Barcode package. This allows easy migration from GNU Barcode to Zint. Zint, 
however, uses none of the same function names or option names as GNU Barcode. 
This allows you to use both packages in your application without conflict if 
you wish. 

5.1 Creating and Deleting Symbols
---------------------------------
The symbols manipulated by Zint are held in a zint_symbol structure defined in 
zint.h. These symbols are created with the ZBarcode_Create() function and 
deleted using the ZBarcode_Delete() function. For example the following code 
creates and then deletes a symbol:

#include <stdio.h>
#include <zint.h>
int main()
{
    struct zint_symbol *my_symbol;my_symbol = ZBarcode_Create();
    if(my_symbol != NULL)
    {
        printf("Symbol successfully created!\n");
    }
    ZBarcode_Delete(my_symbol);
    return 0;
}

When compiling this code it will need to be linked with the libzint library 
using the -lzint option:

gcc -o simple simple.c –lzint

5.2 Encoding and Saving to File
-------------------------------
To encode data in a barcode use the ZBarcode_Encode() function. To write the 
symbol to a file use the ZBarcode_Print() function. For example the following 
code takes a string from the command line and outputs a Code 128 symbol in a 
PNG file named out.png (or a GIF file called out.gif if libpng is not present)
in the current working directory:

#include <stdio.h>
#include <zint.h>
int main(int argc, char **argv)
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();
    ZBarcode_Encode(my_symbol, argv[1], 0);
    ZBarcode_Print(my_symbol, 0);
    ZBarcode_Delete(my_symbol);
    return 0;
}

This can also be done in one stage using the ZBarcode_Encode_and_Print() 
function as shown in the next example:

#include <stdio.h>
#include <zint.h>
int main(int argc, char **argv)
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();
    ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    ZBarcode_Delete(my_symbol);
    return 0;
}

Input data should be Unicode (UTF-8) formatted.

5.3 Encoding and Printing Functions in Depth
--------------------------------------------
The functions for encoding and printing barcodes are defined as:

int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input, int 
length);

int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename);

int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);

int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, 
      int length, int rotate_angle);

int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, 
      int rotate_angle);

In these definitions "length" can be used to set the length of the input 
string. This allows the encoding of NULL (ASCII 0) characters in those 
symbologies which allow this. A value of 0 will disable this function and Zint 
will encode data up to the first NULL character in the input string.

The "rotate_angle" value can be used to rotate the image when outputting as a 
raster image. Valid values are 0, 90, 180 and 270.

The ZBarcode_Encode_File() and ZBarcode_Encode_File_and_Print() functions can 
be used to encode data read directly from a text file where the filename is given
in the "filename" string. 

5.4 Buffering Symbols in Memory
-------------------------------
In addition to saving barcode images to file Zint allows you to access a 
representation of the resulting bitmap image in memory. The following functions 
allow you to do this: 

int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle); 

int ZBarcide_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char 
      *input, int length, int rotate_angle); 

int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, 
      int rotate_angle); 

The arguments here are the same as above. The difference is that instead of 
saving the image to file it is placed in a character array. The "bitmap" 
pointer is set to the first memory location in the array and the values 
"barcode_width" and "barcode_height" indicate the size of the resulting image 
in pixels. Rotation and colour options can be used at the same time as using 
the buffer functions in the same way as when saving to a raster image. The
pixel data can be extracted from the character array by the methd shown in
the example below where render_pixel() is assumed to be a function for drawing
a pixel on the screen implemented by the external application:

int row, col, i = 0;
int red, blue, green;

for (row = 0; row < my_symbol->bitmap_height; row++) {
     for (column = 0; column < my_symbol->bitmap_width; column++) {
          red = my_symbol->bitmap[i];
          green = my_symbol->bitmap[i + 1];
          blue = my_symbol->bitmap[i + 2];
          render_pixel(row, column, red, green, blue);
          i += 3;
     }
}

5.5 Setting Options
-------------------
So far our application is not very useful unless we plan to only make Code 128 
symbols and we don't mind that they only save to out.png. As with the CLI 
program, of course, these options can be altered. The way this is done is 
by altering the contents of the zint_symbol structure between the creation and 
encoding stages. The zint_symbol structure consists of the following variables: 

-------------------------------------------------------------------------------
Variable Name    | Type         | Meaning                     | Default Value
-------------------------------------------------------------------------------
symbology        | integer      | Symbol to use (see section  | BARCODE_CODE128
                 |              |    5.7).                    | 
height           | integer      | Symbol height. [1]          | 50
whitespace_width | integer      | Whtespace width.            | 0
border_width     | integer      | Border width.               | 0
output_options   | integer      | Set various output file     | (none)
                 |              |    parameters (see section  |
                 |              |    5.8). [2]                |
fgcolour         | character    | Foreground (ink) colour as  | "000000"
                 |    string    |    RGB hexadecimal string.  |
                 |              |    Must be 6 characters     |
                 |              |    followed by terminating  |
                 |              |    \0 character.            |
bgcolour         | character    | Background (paper) colour   | "ffffff"
                 |    string    |    as RGB hexadecimal       |
                 |              |    string. Must be 6 chara- |
                 |              |    ters followed by termin- |
                 |              |    ating \0 character.      |
outfile          | character    | Contains the name of the    | "out.png"
                 |    string    |    file to output a result- |
                 |              |    ing barcode symbol to.   |
                 |              |    Must end in .png, .gif,  |
                 |              |    .eps, .pcx, .svg or .txt |
option_1         | integer      | Symbol specific options.    | (automatic)
option_2         | integer      | Symbol specific options.    | (automatic)
option_3         | integer      | Symbol specific options.    | (automatic)
scale            | float        | Scale factor for adjusting  | 1.0
                 |              |    size of image.           |
input_mode       | integer      | Set encoding of input data  | UNICODE_MODE
                 |              |    (see section 5.9)        |
eci              | integer      | Extended Channel Interpre-  | 3
                 |              |    tation mode.             |
primary          | character    | Primary message data for    | NULL
                 |    string    |    more complex symbols.    |
text             | unsigned     | Human readable text, which  | NULL
                 |    character |    usually consists of in-  |
                 |    string    |    put data plus one more   |
                 |              |    check digit. Uses UTF-8  |
                 |              |    formatting.              |
show_hrt         | integer      | Set to 0 to hide text.      | 1
dot_size         | float        | Size of dots used in dotty  | 4.0 / 5.0
                 |              |    mode.                    |
rows             | integer      | Number of rows used by the  | (output only)
                 |              |    the symbol.              |
width            | integer      | Width of the generated sym- | (output only)
                 |              |    bol.                     |
encoding_data    | array of     | Representation of the       | (output only)
                 |    character |    encoded data.            |
                 |    strings   |                             |
row_height       | array of     | Representation of the       | (output only)
                 |    integers  |    height of a row.         |
errtxt           | character    | Error message in the event  | (output only)
                 |    string    |    that an error ocurred.   |
bitmap           | pointer to   | Pointer to stored bitmap    | (output only)
                 |    character |    image.                   |
                 |    array     |                             |
bitmap_width     | integer      | Width of stored bitmap      | (output only)
                 |              |    image (in pixels).       |
bitmap_height    | integer      | Height of stored bitmap     | (output only)
                 |              |    image (in pixels).       |
-------------------------------------------------------------------------------

To alter these values use the syntax shown in the example below. This code has 
the same result as the previous example except the output is now taller and 
plotted in green.

#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
    struct zint_symbol *my_symbol;my_symbol = ZBarcode_Create();
    strcpy(my_symbol->fgcolour, "00ff00");
    my_symbol->height = 400;
    ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    ZBarcode_Delete(my_symbol);
    return 0;
}

5.6 Handling Errors
-------------------
If errors occur during encoding an integer value is passed back to the calling 
application. In addition the errtxt value is used to give a message detailing 
the nature of the error. The errors generated by Zint are given in the table 
below: 

-------------------------------------------------------------------------------
Return Value                 |  Meaning
-------------------------------------------------------------------------------
ZINT_WARN_INVALID_OPTION     |  One of the values in zint_struct was set
                             |     incorrectly but Zint has made a guess at
                             |     what it should have been and generated a
                             |     barcode accordingly.
ZINT_WARN_USES_ECI           |  Zint has automatically inserted an ECI 
                             |     character. The symbol may not be readable
                             |     with some readers.
ZINT_ERROR_TOO_LONG          |  The input data is too long or too short for the
                             |     selected symbology. No symbol has been
                             |     generated. 
ZINT_ERROR_INVALID_DATA      |  The data to be encoded includes characters which
                             |     are not permitted by the selected symbology
                             |     (e.g. alphabetic characters in an EAN
                             |     symbol). No symbol has been generated. 
ZINT_ERROR_INVALID_CHECK     |  An ISBN with an incorrect check digit has been 
                             |     entered. No symbol has been generated. 
ZINT_ERROR_INVALID_OPTION    |  One of the values in zint_struct was set
                             |     incorrectly and Zint was unable to guess what
                             |     it should have been. No symbol has been
                             |     generated. 
ZINT_ERROR_ENCODING_PROBLEM  |  A problem has occurred during encoding of the
                             |     data. This should never happen. Please
                             |     contact the developer if you encounter this
                             |     error. 
ZINT_ERROR_FILE_ACCESS       |  Zint was unable to open the requested output
                             |     file. This is usually a file permissions
                             |     problem.
ZINT_ERROR_MEMORY            |  Zint ran out of memory. This should only be a
                             |     problem with legacy systems.
-------------------------------------------------------------------------------

To catch errors use an integer variable as shown in the code below:

#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
    struct zint_symbol *my_symbol;
    int error = 0;
    my_symbol = ZBarcode_Create();
    strcpy(my_symbol->fgcolour, "nonsense");
    error = ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    if(error != 0)
    {
    /* some error occurred */
        printf("%s\n", my_symbol->errtxt);
    }
    if(error > WARN_INVALID_OPTION)
    {
    /* stop now */
        ZBarcode_Delete(my_symbol);
    return 1;
    }
    /* otherwise carry on with the rest of the application */
    ZBarcode_Delete(my_symbol);
    return 0;
}

This code will exit with the appropriate message:

error: malformed foreground colour target

5.7 Specifying a Symbology
--------------------------
Symbologies can be specified by number or by name as shown in the following 
table. For example

symbol->symbology= BARCODE_LOGMARS;

means the same as

symbol->symbology = 50;

--------------------------------------------------------------------------------
Numeric | Name                    | Barcode Name
Value   | 
--------------------------------------------------------------------------------
1       | BARCODE_CODE11          | Code 11
2       | BARCODE_C25MATRIX       | Standard Code 2 of 5
3       | BARCODE_C25INTER        | Interleaved 2 of 5
4       | BARCODE_C25IATA         | Code 2 of 5 IATA
6       | BARCODE_C25LOGIC        | Code 2 of 5 Data Logic
7       | BARCODE_C25IND          | Code 2 of 5 Industrial
8       | BARCODE_CODE39          | Code 3 of 9 (Code 39)
9       | BARCODE_EXCODE39        | Extended Code 3 of 9 (Code 39+)
13      | BARCODE_EANX            | EAN
14      | BARCODE_EANX_CHK        | EAN + Check Digit
16      | BARCODE_EAN128          | GS1-128 (UCC.EAN-128)
18      | BARCODE_CODABAR         | Codabar
20      | BARCODE_CODE128         | Code 128 (automatic subset switching)
21      | BARCODE_DPLEIT          | Deutshe Post Leitcode
22      | BARCODE_DPIDENT         | Deutshe Post Identcode
23      | BARCODE_CODE16K         | Code 16K
24      | BARCODE_CODE49          | Code 49
25      | BARCODE_CODE93          | Code 93
28      | BARCODE_FLAT            | Flattermarken
29      | BARCODE_RSS14           | GS1 DataBar-14
30      | BARCODE_RSS_LTD         | GS1 DataBar Limited
31      | BARCODE_RSS_EXP         | GS1 DataBar Extended
32      | BARCODE_TELEPEN         | Telepen Alpha
34      | BARCODE_UPCA            | UPC A
35      | BARCODE_UPCA_CHK        | UPC A + Check Digit
37      | BARCODE_UPCE            | UPC E
38      | BARCODE_UPCE            | UPC E + Check Digit
40      | BARCODE_POSTNET         | PostNet
47      | BARCODE_MSI_PLESSEY     | MSI Plessey
49      | BARCODE_FIM             | FIM
50      | BARCODE_LOGMARS         | LOGMARS
51      | BARCODE_PHARMA          | Pharmacode One-Track
52      | BARCODE_PZN             | PZN
53      | BARCODE_PHARMA_TWO      | Pharmacode Two-Track
55      | BARCODE_PDF417          | PDF417
56      | BARCODE_PDF417TRUNC     | PDF417 Truncated
57      | BARCODE_MAXICODE        | Maxicode
58      | BARCODE_QRCODE          | QR Code
60      | BARCODE_CODE128B        | Code 128 (Subset B)
63      | BARCODE_AUSPOST         | Australia Post Standard Customer
66      | BARCODE_AUSREPLY        | Australia Post Reply Paid
67      | BARCODE_AUSROUTE        | Australia Post Routing
68      | BARCODE_AUSDIRECT       | Australia Post Redirection
69      | BARCODE_ISBNX           | ISBN (EAN-13 with verification stage)
70      | BARCODE_RM4SCC          | Royal Mail 4 State (RM4SCC)
71      | BARCODE_DATAMATRIX      | Data Matrix ECC200
72      | BARCODE_EAN14           | EAN-14
74      | BARCODE_CODABLOCKF      | Codablock-F
75      | BARCODE_NVE18           | NVE-18
76      | BARCODE_JAPANPOST       | Japanese Postal Code
77      | BARCODE_KOREAPOST       | Korea Post
79      | BARCODE_RSS14STACK      | GS1 DataBar-14 Stacked
80      | BARCODE_RSS14STACK_OMNI | GS1 DataBar-14 Stacked Omnidirectional
81      | BARCODE_RSS_EXPSTACK    | GS1 DataBar Expanded Stacked
82      | BARCODE_PLANET          | PLANET
84      | BARCODE_MICROPDF417     | MicroPDF417
85      | BARCODE_ONECODE         | USPS OneCode
86      | BARCODE_PLESSEY         | Plessey Code
87      | BARCODE_TELEPEN_NUM     | Telepen Numeric
89      | BARCODE_ITF14           | ITF-14
90      | BARCODE_KIX             | Dutch Post KIX Code
92      | BARCODE_AZTEC           | Aztec Code
93      | BARCODE_DAFT            | DAFT Code
97      | BARCODE_MICROQR         | Micro QR Code
98      | BARCODE_HIBC_128        | HIBC Code 128
99      | BARCODE_HIBC_39         | HIBC Code 39
102     | BARCODE_HIBC_39         | HIBC Data Matrix ECC200
104     | BARCODE_HIBC_DM         | HIBC QR Code
106     | BARCODE_HIBC_PDF        | HIBC PDF417
108     | BARCODE_HIBC_MICPDF     | HIBC MicroPDF417
112     | BARCODE_HIBC_AZTEC      | HIBC Aztec Code
115     | BARCODE_DOTCODE         | DotCode
116     | BARCODE_HANXIN          | Han Xin (Chinese Sensible) Code
128     | BARCODE_AZRUNE          | Aztec Runes
129     | BARCODE_CODE32          | Code 32
130     | BARCODE_EANX_CC         | Composite Symbol with EAN linear component
131     | BARCODE_EAN128_CC       | Composite Symbol with GS1-128 linear 
        |                         |    component
132     | BARCODE_RSS14_CC        | Composite Symbol with GS1 DataBar-14 linear 
        |                         |    component
133     | BARCODE_RSS_LTD_CC      | Composite Symbol with GS1 DataBar Limited 
        |                         |    component
134     | BARCODE_RSS_EXP_CC      | Composite Symbol with GS1 DataBar Extended 
        |                         |    component
135     | BARCODE_UPCA_CC         | Composite Symbol with UPC A linear component
136     | BARCODE_UPCE_CC         | Composite Symbol with UPC E linear component
137     | BARCODE_RSS14STACK_CC   | Composite Symbol with GS1 DataBar-14 
        |                         |    Stacked component
138     | BARCODE_RSS14_OMNI_CC   | Composite Symbol with GS1 DataBar-14 
        |                         |    Stacked Omnidirectional component
139     | BARCODE_RSS_EXPSTACK_CC | Composite Symbol with GS1 DataBar Expanded 
        |                         |    Stacked component
140     | BARCODE_CHANNEL         | Channel Code
141     | BARCODE_CODEONE         | Code One
142     | BARCODE_GRIDMATRIX      | Grid Matrix
--------------------------------------------------------------------------------

5.8 Adjusting other output options
----------------------------------
The output_options variable can be used to adjust various aspects of the output
file. To select more than one option from the table below simply add them together
when adjusting this value:

my_symbol->output_options += BARCODE_BIND + READER_INIT;

--------------------------------------------------------------------------------
Value               |  Effect
--------------------------------------------------------------------------------
0                   |  No options selected.
BARCODE_BIND        |  Boundary bars above and below the symbol and between
                    |     rows if stacking multiple symbols. [2]
BARCODE_BOX         |  Add a box surrounding the symbol and whitespace. [2]
BARCODE_STDOUT      |  Output the file to stdout.
READER_INIT         |  Add a reader initialisation symbol to the data before
                    |     encoding.
SMALL_TEXT          |  Use a smaller font for the human readable text.
BOLD_TEXT           |  Embolden the human readable text.
CMYK_COLOUR         |  Select the CMYK colour space option for encapsulated
                    |      PostScript files.
BARCODE_DOTTY_MODE  |  Plot a matrix symbol using dots rather than squares.
--------------------------------------------------------------------------------

5.9 Setting the Input Mode
--------------------------
The way in which the input data is encoded can be set using the input_mode 
property. Valid values are shown in the table below. 

-----------------------------------------------------------------------------
Value         |  Effect
-----------------------------------------------------------------------------
DATA_MODE     |  Uses full ASCII range interpreted as Latin-1 or binary data.
UNICODE_MODE  |  Uses pre-formatted UTF-8 input.
GS1_MODE      |  Encodes GS1 data using FNC1 characters.
-----------------------------------------------------------------------------

5.10 Verifying Symbology Availability
-------------------------------------
An additional function available in the API is defined as:

int ZBarcode_ValidID(int symbol_id);

This function allows you to check whether a given symbology is available. A 
non-zero return value indicates that the given symbology is available. For 
example:

if(ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    printf("PDF417 available");
} else {
    printf("PDF417 not available");
}

[1] This value is ignored for Australia Post 4-State Barcodes, PostNet, PLANET, 
USPS OneCode, RM4SCC, PDF417, Data Matrix ECC200, Maxicode, QR Code, GS1 
DataBar-14 Stacked, PDF417 and MicroPDF417 - all of which have a fixed height.

[2] This value is ignored for Code 16k, Codablock-F and ITF-14 symbols.

6. Types of Symbology
=====================
6.1 One-Dimensional Symbols
---------------------------
One-Dimensional Symbols are what most people associate with the term barcode. 
They consist of a number of bars and a number of spaces of differing widths.

6.1.1 Code 11
-------------
Developed by Intermec in 1977, Code 11 is similar to Code 2 of 5 Matrix and is 
primarily used in telecommunications. The symbol can encode any length string 
consisting of the digits 0-9 and the dash character (-). One modulo-11 check 
digit is calculated.

6.1.2 Code 2 of 5
-----------------
Code 2 of 5 is a family of one-dimensional symbols, 8 of which are supported by 
Zint. Note that the names given to these standards alters from one source to 
another so you should take care to ensure that you have the right barcode type 
before using these standards.

6.1.2.1 Standard Code 2 of 5
----------------------------
Also known as Code 2 of 5 Matrix is a self-checking code used in industrial 
applications and photo development. Standard Code 2 of 5 will encode any length 
numeric input (digits 0-9).

6.1.2.2 IATA Code 2 of 5
------------------------
Used for baggage handling in the air-transport industry by the International 
Air Transport Agency, this self-checking code will encode any length numeric input 
(digits 0-9) and does not include a check digit.

6.1.2.3 Industrial Code 2 of 5
------------------------------
Industrial Code 2 of 5 can encode any length numeric input (digits 0-9) and 
does not include a check digit.

6.1.2.4 Interleaved Code 2 of 5
-------------------------------
This self-checking symbology encodes pairs of numbers, and so can only encode 
an even number of digits (0-9). If an odd number of digits is entered a leading 
zero is added by Zint. No check digit is added.

6.1.2.5 Code 2 of 5 Data Logic
------------------------------
Data Logic does not include a check digit and can encode any length numeric 
input (digits 0-9).

6.1.2.6 ITF-14
--------------
ITF-14, also known as UPC Shipping Container Symbol or Case Code is based on 
Interleaved Code 2 of 5 and requires a 13 digit numeric input (digits 0-9). One 
modulo-10 check digit is added by Zint.

6.1.2.7 Deutsche Post Leitcode
------------------------------
Leitcode is based on Interleaved Code 2 of 5 and is used by Deutsche Post for 
mailing purposes. Leitcode requires a 13-digit numerical input and includes a 
check digit.

6.1.2.8 Deutsche Post Identcode
-------------------------------
Identcode is based on Interleaved Code 2 of 5 and is used by Deutsche Post for 
mailing purposes. Identcode requires an 11-digit numerical input and includes a 
check digit.

6.1.3 Universal Product Code (EN 797)
-------------------------------------
6.1.3.1 UPC Version A
---------------------
UPC-A is used in the United States for retail applications. The symbol requires 
an 11 digit article number. The check digit is calculated by Zint. In addition 
EAN-2 and EAN-5 add-on symbols can be added using the + character. For example, 
to draw a UPC-A symbol with the data 72527270270 with an EAN-5 add-on showing 
the data 12345 use the command:

zint --barcode=34 -d 72527270270+12345

or encode a data string with the + character included:

my_symbol->symbology = BARCODE_UPCA;

error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345");

If your input data already includes the check digit symbology 35 can be used
which takes a 12 digit input and validates the check digit before encoding.

6.1.3.2 UPC Version E
---------------------
UPC-E is a zero-compressed version of UPC-A developed for smaller packages. The 
code requires a 6 digit article number (digits 0-9). The check digit is 
calculated by Zint. EAN-2 and EAN-5 add-on symbols can be added using the + 
character as with UPC-A. In addition Zint also supports Number System 1 
encoding by entering a 7-digit article number stating with the digit 1. For
example:

zint --barcode=37 -d 1123456

or

my_symbol->symbology = BARCODE_UPCE;

error = ZBarcode_Encode_and_Print(my_symbol, "1123456");

If your input data already includes the check digit symbology 38 can be used
which takes a 7 or 8 digit input and validates the check digit before encoding.

6.1.4 European Article Number (EN 797)
--------------------------------------
6.1.4.1 EAN-2, EAN-5, EAN-8 and EAN-13
--------------------------------------
The EAN system is used in retail across Europe and includes standards for EAN-2 
and EAN-5 add-on codes, EAN-8 and EAN-13 which encode 2, 5, 7 or 12 digit 
numbers respectively. Zint will decide which symbology to use depending on the 
length of the input data. In addition EAN-2 and EAN-5 add-on symbols can be 
added using the + symbol as with UPC symbols. For example:

zint --barcode=13 -d 54321

will encode a stand-alone EAN-5, whereas

zint --barcode=13 -d 7432365+54321

will encode an EAN-8 symbol with an EAN-5 add-on. As before these results can 
be achieved using the API:

my_symbol->symbology = BARCODE_EANX;

error = ZBarcode_Encode_and_Print(my_symbol, "54321");

error = ZBarcode_Encode_and_Print(my_symbol, "7432365+54321");

All of the EAN symbols include check digits which are added by Zint.

If you are encoding an EAN-8 or EAN-13 symbol and your data already includes
the check digit then you can use symbology 14 which takes an 8 or 13 digit input
and validates the check digit before encoding.

6.1.4.2 SBN, ISBN and ISBN-13
-----------------------------
EAN-13 symbols (also known as Bookland EAN-13) can also be produced from 
9-digit SBN, 10-digit ISBN or 13-digit ISBN-13 data. The relevant check digit needs
to be present in the input data and will be verified before the symbol is 
generated. In addition EAN-2 and EAN-5 add-on symbols can be added using the + 
symbol as with UPC symbols.

6.1.5 Plessey
-------------
Also known as Plessey Code, this symbology was developed by the Plessey Company 
Ltd. in the UK. The symbol can encode any length data consisting of digits 
(0-9) or letters A-F and includes a CRC check digit. 

6.1.6 MSI Plessey
-----------------
Based on Plessey and developed by MSE Data Corporation, MSI Plessey is 
available with a range of check digit options available by setting option_2 or 
by using the --ver= switch. Any length numeric (digits 0-9) input can be 
encoded. The table below shows the options available: 

-------------------------------------------
Value of option_2  |  Check Digits
-------------------------------------------
0                  |  None
1                  |  Modulo-10
2                  |  Modulo-10 & Modulo-10
3                  |  Modulo-11
4                  |  Modulo-11 & Modulo-10
-------------------------------------------

6.1.7 Telepen
-------------
6.1.7.1 Telepen Alpha
---------------------
Telepen Alpha was developed by SB Electronic Systems Limited and can encode any 
length of ASCII text input. Telepen includes a modulo-127 check digit.

6.1.7.2 Telepen Numeric
-----------------------
Telepen Numeric allows compression of numeric data into a Telepen symbol. Data 
can consist of pairs of numbers or pairs consisting of a numerical digit 
followed an X character. For example: 466333 and 466X33 are valid codes whereas 
46X333 is not (the digit pair "X3" is not valid). Telepen Numeric includes a
modulo-127 check digit which is added by Zint. 

6.1.8 Code 39
-------------
6.1.8.1 Standard Code 39 (ISO 16388)
------------------------------------
Standard Code 39 was developed in 1974 by Intermec. Input data can be of any 
length and can include the characters 0-9, A-Z, dash (-), full stop (.), space, 
asterisk (*), dollar ($), slash (/), plus (+) and percent (%). The standard 
does not require a check digit but a modulo-43 check digit can be added if 
required by setting option_2 = 1 or using --ver=1.

6.1.8.2 Extended Code 39
------------------------
Also known as Code 39e and Code39+, this symbology expands on Standard Code 39 
to provide support to the full ASCII character set. The standard does not 
require a check digit but a modulo-43 check digit can be added if required by 
setting option_2 = 1 or using --ver=1.

6.1.8.3 Code 93
---------------
A variation of Extended Code 39, Code 93 also supports full ASCII text. Two 
check digits are added by Zint.

6.1.8.4 PZN
-----------
PZN is a Code 39 based symbology used by the pharmaceutical industry in 
Germany. PZN encodes a 6 digit number to which Zint will add a modulo-10
check digit.

6.1.8.5 LOGMARS
---------------
LOGMARS (Logistics Applications of Automated Marking and Reading Symbols) is a 
variation of the Code 39 symbology used by the US Department of Defence. 
LOGMARS encodes the same character set as Standard Code 39 and adds a modulo-43 
check digit.

6.1.8.6 Code 32
---------------
A variation of Code 39 used by the Italian Ministry of Health ("Ministero della 
Sanità") for encoding identifiers on pharmaceutical products. This symbology
requires a numeric input up to 8 digits in length. A check digit is added by Zint.

6.1.8.7 HIBC Code 39
--------------------
This option adds a leading '+' character and a trailing modulo-49 check digit 
to a standard Code 39 symbol as required by the Health Industry Barcode 
standards. 

6.1.9 Codabar (EN 798)
----------------------
Also known as NW-7, Monarch, ABC Codabar, USD-4, Ames Code and Code 27, this 
symbology was developed in 1972 by Monarch Marketing Systems for retail 
purposes. The American Blood Commission adopted Codabar in 1977 as the standard 
symbology for blood identification. Codabar can encode any length string 
starting and ending with the letters A-D and containing between these letters 
the numbers 0-9, dash (-), dollar ($), colon (:), slash (/), full stop (.) or 
plus (+). No check digit is generated.

6.1.10 Pharmacode
-----------------
Developed by Laetus, Pharmacode is used for the identification of 
pharmaceuticals. The symbology is able to encode whole numbers between 3 and 
131070. 

6.1.11 Code 128
---------------
6.1.11.1 Standard Code 128 (ISO 15417)
--------------------------------------
One of the most ubiquitous one-dimensional barcode symbologies, Code 128 was 
developed in 1981 by Computer Identics. This symbology supports full ASCII text 
and uses a three-mode system to compress the data into a smaller symbol. Zint 
automatically switches between modes and adds a modulo-103 check digit. Code 
128 is the default barcode symbology used by Zint. In addition Zint supports 
the encoding of Latin-1 (non-English) characters in Code 128 symbols [1]. The 
Latin-1 character set is shown in Appendix A.

6.1.11.2 Code 128 Subset B
--------------------------
It is sometimes advantageous to stop Code 128 from using subset mode C which 
compresses numerical data. The BARCODE_CODE128B option (symbology 60) 
suppresses mode C in favour of mode B.

6.1.11.3 GS1-128
----------------
A variation of Code 128 also known as UCC/EAN-128, this symbology is defined by 
the GS1 General Specification. Application Identifiers (AIs) should be entered 
using [square bracket] notation. These will be converted to (round brackets) 
for the human readable text. This will allow round brackets to be used in the 
data strings to be encoded. Fixed length data should be entered at the 
appropriate length for correct encoding (see Appendix C). GS1-128 does not 
support extended ASCII characters. Check digits for GTIN data (AI 01) are not 
generated and need to be included in the input data. The following is an example
of a valid GS1-128 input:

zint --barcode=16 -d "[01]98898765432106[3202]012345[15]991231"

6.1.11.4 EAN-14
---------------
A shorter version of GS1-128 which encodes GTIN data only. A 13 digit number is 
required. The GTIN check digit and AI (01) are added by Zint.

6.1.11.5 NVE-18
---------------
A variation of Code 128 the "Nummer der Versandeinheit" standard includes both 
modulo-10 and modulo-103 check digits. NVE-18 requires a 17 digit numerical 
input and check digits are added by Zint.

6.1.11.6 HIBC Code 128
----------------------
This option adds a leading '+' character and a trailing modulo-49 check digit 
to a standard Code 128 symbol as required by the Health Industry Barcode 
standards. 

6.1.12 GS1 DataBar (ISO 24724)
------------------------------
Also known as RSS (Reduced Spaced Symbology) these symbols are due to replace 
GS1-128 symbols in accordance with the GS1 General Specification. If a GS1
DataBar symbol is to be printed with a 2D component as specified in ISO 24723
set option_1 = 2 or use the option --mode=2 at the command prompt. See section
6.3 of this manual to find out how to generate DataBar symbols with 2D components.

6.1.12.1 DataBar-14 and DataBar-14 Truncated
--------------------------------------------
Also known as RSS-14 this standard encodes a 13 digit item code. A check digit 
and application identifier of (01) are added by Zint. To produce a truncated
symbol set the symbol height to a value between 32 and 13. Normal DataBar-14
symbols should have a height of 33 or greater.

6.1.12.2 DataBar Limited
------------------------
Also known as RSS Limited this standard encodes a 13 digit item code and can be 
used in the same way as DataBar-14 above. DataBar Limited, however, is limited 
to data starting with digits 0 and 1 (i.e. numbers in the range 0 to 
1999999999999). As with DataBar-14 a check digit and application identifier of 
(01) are added by Zint.

6.1.12.3 DataBar Expanded
-------------------------
Also known as RSS Expanded this is a variable length symbology capable of 
encoding data from a number of AIs in a single symbol. AIs should be encased in 
[square brackets] in the input data. This will be converted to (rounded 
brackets) before it is included in the human readable text attached to the 
symbol. This method allows the inclusion of rounded brackets in the data to be 
encoded. GTIN data (AI 01) should also include the check digit data as this is 
not calculated by Zint when this symbology is encoded. Fixed length data should
be entered at the appropriate length for correct encoding (see Appendix C). The
following is an example of a valid DataBar Expanded input:

zint --barcode=31 -d "[01]98898765432106[3202]012345[15]991231" 

6.1.13 Korea Post Barcode
-------------------------
The Korean Postal Barcode is used to encode a six-digit number and includes one 
check digit. 

6.1.14 Channel Code
-------------------
A highly compressed symbol for numeric data. The number of channels in the 
symbol can be between 3 and 8 and this can be specified by setting the value of 
option_2. It can also be determined by the length of the input data e.g. a 
three character input string generates a 4 channel code by default. The maximum 
values permitted depend on the number of channels used as shown in the table 
below: 

--------------------------------------------
Channels  |  Minimum Value  |  Maximum Value
--------------------------------------------
3         |  00             |  26
4         |  000            |  292
5         |  0000           |  3493
6         |  00000          |  44072
7         |  000000         |  576688
8         |  0000000        |  7742862
--------------------------------------------

6.2 Stacked Symbologies
-----------------------
6.2.1 Basic Symbol Stacking
---------------------------
An early innovation to get more information into a symbol, used primarily in 
the vehicle industry, is to simply stack one-dimensional codes on top of each 
other. This can be achieved at the command prompt by giving more than one set 
of input data. For example

zint -d 'This' -d 'That'

will draw two Code 128 symbols, one on top of the other. The same result can be 
achieved using the API by executing the ZBarcode_Encode() function more than 
once on a symbol. For example:

my_symbol->symbology = BARCODE_CODE128;

error = ZBarcode_Encode(my_symbol, "This");

error = ZBarcode_Encode(my_symbol, "That");

error = ZBarcode_Print(my_symbol);

A more sophisticated method is to use some type of line indexing which 
indicates to the barcode reader which order the symbols should be read. This is 
demonstrated by the symbologies below.

6.2.2 Codablock-F
-----------------
This is a stacked symbology based on Code 128 which can encode ASCII code set
data up to a maximum length of 2725 characters. The width of the Codablock-F
symbol can be set using the --cols= option at the command line or option_2.
Alternatively the height (number of rows) can be set using the --rows= option
at the command line or by setting option_1. Zint does not support encoding of
GS1 data in Codablock-F symbols.

6.2.3 Code 16k (EN 12323)
-------------------------
Code 16k uses a Code 128 based system which can stack up to 16 rows in a block.
This gives a maximum data capacity of 77 characters or 154 numerical digits and
includes two modulo-107 check digits. Code 16k also supports extended ASCII
character encoding in the same manner as Code 128. 

6.2.4 PDF417 (ISO 15438)
------------------------
Heavily used in the parcel industry, the PDF417 symbology can encode a vast 
amount of data into a small space. Zint supports encoding up to the ISO 
standard maximum symbol size of 925 codewords which (at error correction level 
0) allows a maximum data size of 1850 text characters, or 2710 digits. The 
width of the generated PDF417 symbol can be specified at the command line using 
the --cols switch followed by a number between 1 and 30, and the amount of 
check digit information can be specified by using the --security switch 
followed by a number between 0 and 8 where the number of codewords used for 
check information is determined by 2^(value + 1). If using the API these values 
are assigned to option_2 and option_1 respectively. The default level of check 
information is determined by the amount of data being encoded. This symbology 
uses Latin-1 character encoding by default but also supports the ECI encoding 
mechanism. A separate symbology ID can be used to encode Health Industry 
Barcode (HIBC) data which adds a leading '+' character and a modulo-49 check 
digit to the encoded data. 

6.2.5 Compact PDF417
--------------------
Also known as truncated PDF417. Options are the same as for PDF417 above.

6.2.6 MicroPDF417 (ISO 24728)
-----------------------------
A variation of the PDF417 standard, MicroPDF417 is intended for applications 
where symbol size needs to be kept to a minimum. 34 predefined symbol sizes are 
available with 1 - 4 columns and 4 - 44 rows. The maximum size MicroPDF417 
symbol can hold 250 alphanumeric characters or 366 digits. The amount of error 
correction used is dependent on symbol size. The number of columns used can be 
determined using the --cols switch or option_2 as with PDF417. This symbology 
uses Latin-1 character encoding by default but also supports the ECI encoding 
mechanism. A separate symbology ID can be used to encode Health Industry 
Barcode (HIBC) data which adds a leading '+' character and a modulo-49 check 
digit to the encoded data. 

6.2.7 GS1 DataBar-14 Stacked (ISO 24724)
----------------------------------------
A stacked variation of the GS1 DataBar-14 symbol requiring the same input (see 
section 6.1.12.1). The height of this symbol is fixed. The data is encoded in 
two rows of bars with a central finder pattern. This symbol can be generated 
with a two-dimensional component to make a composite symbol. 

6.2.8 GS1 DataBar-14 Stacked Omnidirectional (ISO 24724)
--------------------------------------------------------
Another variation of the GS1 DataBar-14 symbol requiring the same input (see 
section 6.1.12.1). The data is encoded in two rows of bars with a central 
finder pattern. This symbol can be generated with a two-dimensional component 
to make a composite symbol. 

6.2.9 GS1 DataBar Expanded Stacked (ISO 24724)
----------------------------------------------
A stacked variation of the GS1 DataBar Expanded symbol for smaller packages. 
Input is the same as for GS1 DataBar Expanded (see section 6.1.12.3). In 
addition the width of the symbol can be altered using the --cols switch or 
option_2. In this case the number of columns relates to the number of character 
pairs on each row of the symbol. This symbol can be generated with a two-
dimensional component to make a composite symbol. For symbols with a 2D component
the number of columns must be at least 2.

6.2.10 Code 49
-------------
Developed in 1987 at Intermec, Code 49 is a cross between UPC and Code 39. It 
it one of the earliest stacked symbologies and influenced the design of Code 
16K a few years later. It supports full 7-bit ASCII input up to a maximum of 49 
characters or 81 numeric digits. GS1 data encoding is also supported. 

6.3 Composite Symbols (ISO 24723)
---------------------------------
Composite symbols employ a mixture of components to give more comprehensive 
information about a product. The permissible contents of a composite symbol is 
determined by the terms of the GS1 General Specification. Composite symbols 
consist of a linear component which can be an EAN, UPC, GS1-128 or GS1 DataBar 
symbol, a 2D component which is based on PDF417 or MicroPDF417, and a separator 
pattern. The type of linear component to be used is determined using the -b or 
--barcode= switch or by adjusting symbol->symbology as with other encoding 
methods. Valid values are shown below. 

--------------------------------------------------------------------------------
Numeric | Name                    | Barcode Name
Value   | 
--------------------------------------------------------------------------------
130     | BARCODE_EANX_CC         | Composite Symbol with EAN linear component
131     | BARCODE_EAN128_CC       | Composite Symbol with GS1-128 linear 
        |                         |    component
132     | BARCODE_RSS14_CC        | Composite Symbol with GS1 DataBar-14 linear 
        |                         |    component
133     | BARCODE_RSS_LTD_CC      | Composite Symbol with GS1 DataBar Limited 
        |                         |    component
134     | BARCODE_RSS_EXP_CC      | Composite Symbol with GS1 DataBar Extended 
        |                         |    component
135     | BARCODE_UPCA_CC         | Composite Symbol with UPC A linear component
136     | BARCODE_UPCE_CC         | Composite Symbol with UPC E linear component
137     | BARCODE_RSS14STACK_CC   | Composite Symbol with GS1 DataBar-14 
        |                         |    Stacked component
138     | BARCODE_RSS14_OMNI_CC   | Composite Symbol with GS1 DataBar-14 
        |                         |    Stacked Omnidirectional component
139     | BARCODE_RSS_EXPSTACK_CC | Composite Symbol with GS1 DataBar Expanded 
        |                         |    Stacked component
--------------------------------------------------------------------------------

The data to be encoded in the linear component of a composite symbol should be 
entered into a primary string with the data for the 2D component being entered 
in the normal way. To do this at the command prompt use the --primary= command. 
For example:

zint -b 130 --mode=1 --primary=331234567890 -d "[99]1234-abcd"

This creates an EAN-13 linear component with the data "331234567890" and a 2D 
CC-A (see below) component with the data "(99)1234-abcd". The same results can 
be achieved using the API as shown below:

my_symbol->symbology = 130;

my_symbol->option_1 = 1;

strcpy(my_symbol->primary, "331234567890");

ZBarcode_Encode_and_Print(my_symbol, "[99]1234-abcd");

EAN-2 and EAN-5 add-on data can be used with EAN and UPC symbols using the + 
symbol as described in section 6.1.3 and 5.1.4.

The 2D component of a composite symbol can use one of three systems: CC-A, CC-B 
and CC-C as described below. The 2D component type can be selected 
automatically by Zint dependant on the length of the input string. 
Alternatively the three methods can be accessed using the --mode= prompt 
followed by 1, 2 or 3 for CC-A, CC-B or CC-C respectively, or by using the 
option_1 variable as shown above. 

6.3.1 CC-A
----------
This system uses a variation of MicroPDF417 which optimised to fit into a small 
space. The size of the 2D component and the amount of error correction is 
determined by the amount of data to be encoded and the type of linear component 
which is being used. CC-A can encode up to 56 numeric digits or an alphanumeric 
string of shorter length. To select CC-A use --mode=1.

6.3.2 CC-B
----------
This system uses MicroPDF417 to encode the 2D component. The size of the 2D 
component and the amount of error correction is determined by the amount of 
data to be encoded and the type of linear component which is being used. CC-B 
can encode up to 338 numeric digits or an alphanumeric string of shorter 
length. To select CC-B use --mode=2.

6.3.3 CC-C
----------
This system uses PDF417 and can only be used in conjunction with a GS1-128 
linear component. CC-C can encode up to 2361 numeric digits or an alphanumeric 
string of shorter length. To select CC-C use --mode=3. 

6.4 Two-Track Symbols
---------------------
6.4.1 Two-Track Pharmacode
--------------------------
Developed by Laetus, Pharmacode Two-Track is an alternative system to 
Pharmacode One-Track used for the identification of pharmaceuticals. The 
symbology is able to encode whole numbers between 4 and 64570080.

6.4.2 PostNet
-------------
Used by the United States Postal Service until 2009, the PostNet barcode was 
used for encoding zip-codes on mail items. PostNet uses numerical input data 
and includes a modulo-10 check digit. While Zint will encode PostNet symbols of 
any length, standard lengths as used by USPS were PostNet6 (5 digits ZIP 
input), PostNet10 (5 digit ZIP + 4 digit user data) and PostNet12 (5 digit ZIP 
+ 6 digit user data).

6.4.3 PLANET
------------
Used by the United States Postal Service until 2009, the PLANET (Postal Alpha 
Numeric Encoding Technique) barcode was used for encoding routing data on mail 
items. Planet uses numerical input data and includes a modulo-10 check digit. 
While Zint will encode PLANET symbols of any length, standard lengths used by 
USPS were Planet12 (11 digit input) and Planet14 (13 digit input). 

6.5 4-State Postal Codes
------------------------
6.5.1 Australia Post 4-State Symbols
------------------------------------
6.5.1.1 Customer Barcodes
-------------------------
Australia Post Standard Customer Barcode, Customer Barcode 2 and Customer 
Barcode 3 are 37-bar, 52-bar and 67-bar specifications respectively, developed 
by Australia Post for printing Delivery Point ID (DPID) and customer 
information on mail items. Valid data characters are 0-9, A-Z, a-z, space and 
hash (#). A Format Control Code (FCC) is added by Zint and should not be 
included in the input data. Reed-Solomon error correction data is generated by 
Zint. Encoding behaviour is determined by the length of the input data 
according to the formula shown in the following table: 

-----------------------------------------------------------------
Input  |  Required Input Format    |  Symbol  |  FCC  |  Encoding
Length |                           |  Length  |       |  Table
-----------------------------------------------------------------
8      |  99999999                 |  37-bar  |  11   |  None
13     |  99999999AAAAA            |  52-bar  |  59   |  C
16     |  9999999999999999         |  52-bar  |  59   |  N
18     |  99999999AAAAAAAAAA       |  67-bar  |  62   |  C
23     |  99999999999999999999999  |  67-bar  |  62   |  N
-----------------------------------------------------------------

6.5.1.2 Reply Paid Barcode
--------------------------
A Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which 
requires an 8-digit DPID input.

6.5.1.3 Routing Barcode
-----------------------
A Routing version of the Australia Post 4-State Barcode (FCC 87) which requires 
an 8-digit DPID input.

6.5.1.4 Redirect Barcode
------------------------
A Redirection version of the Australia Post 4-State Barcode (FCC 92) which 
requires an 8-digit DPID input. 

6.5.2 Dutch Post KIX Code
-------------------------
This Symbology is used by Royal Dutch TPG Post (Netherlands) for Postal code 
and automatic mail sorting. Data input can consist of numbers 0-9 and letters 
A-Z and needs to be 11 characters in length. No check digit is included.

6.5.3 Royal Mail 4-State Country Code (RM4SCC)
----------------------------------------------
The RM4SCC standard is used by the Royal Mail in the UK to encode postcode and 
customer data on mail items. Data input can consist of numbers 0-9 and letters 
A-Z and usually includes delivery postcode followed by house number. For 
example "W1J0TR01" for 1 Picadilly Circus in London. Check digit data is 
generated by Zint.

6.5.4 USPS OneCode
------------------
Also known as the Intelligent Mail Barcode and used in the US by the United 
States Postal Service (USPS), the OneCode system replaced the PostNet and 
PLANET symbologies in 2009. OneCode is a fixed length (65-bar) symbol which 
combines routing and customer information in a single symbol. Input data 
consists of a 20 digit tracking code, followed by a dash (-), followed by a 
delivery point zip-code which can be 0, 5, 9 or 11 digits in length. For 
example all of the following inputs are valid data entries:

"01234567094987654321"

"01234567094987654321-01234"

"01234567094987654321-012345678"

"01234567094987654321-01234567891"

6.5.5 Japanese Postal Code
--------------------------
Used for address data on mail items for Japan Post. Accepted values are 0-9, 
A-Z and Dash (-). A modulo 19 check digit is added by Zint.

6.6 Two-Dimensional Matrix Symbols
----------------------------------
6.6.1 Data Matrix ECC200 (ISO 16022)
------------------------------------
Also known as Semacode this symbology was developed in 1989 by Acuity CiMatrix 
in partnership with the US DoD and NASA. The symbol can encode a large amount 
of data in a small area. Data Matrix ECC200 can encode characters in the 
Latin-1 set by default but also supports encoding using other character sets 
using the ECI mechanism. It can also encode GS1 data. The size of the 
generated symbol can also be adjusted using the --vers= option or by setting 
option_2 as shown in the table below. A separate symbology ID can be used to 
encode Health Industry Barcode (HIBC) data which adds a leading '+' character 
and a modulo-49 check digit to the encoded data. Note that only ECC200 encoding 
is supported, the older standards have now been removed from Zint. 

---------------------
Input  |  Symbol Size
---------------------
1      |  10 x 10
2      |  12 x 12
3      |  14 x 14
4      |  16 x 16
5      |  18 x 18
6      |  20 x 20
7      |  22 x 22
8      |  24 x 24
9      |  26 x 26
10     |  32 x 32
11     |  36 x 36
12     |  40 x 40
13     |  44 x 44
14     |  48 x 48
15     |  52 x 52
16     |  64 x 64
17     |  72 x 72
18     |  80 x 80
19     |  88 x 88
20     |  96 x 96
21     |  104 x 104
22     |  120 x 120
23     |  132 x 132
24     |  144 x 144
25     |  8 x 18
26     |  8 x 32
28     |  12 x 26
28     |  12 x 36
29     |  16 x 36
30     |  16 x 48
---------------------

To force Zint only to use square symbols (versions 1-24) at the command line 
use the option --square and when using the API set the value option_3 = 
DM_SQUARE.

Data Matrix Rectangular Extension (DMRE) codes may be generated with the 
following values as before:

---------------------
Input  |  Symbol Size
---------------------
31     |  8 x 48
32     |  8 x 64
33     |  12 x 64
34     |  16 x 64
35     |  24 x 32
36     |  24 x 36
37     |  24 x 48
38     |  24 x 64
39     |  26 x 32
40     |  26 x 40
41     |  26 x 48
42     |  26 x 64
---------------------

DMRE symbol sizes may be activated in automatic size mode using the option 
--dmre or by the API option_3 = DM_DMRE

6.6.2 QR Code (ISO 18004)
-------------------------
Also known as Quick Response Code this symbology was developed by Denso. Four 
levels of error correction are available using the --security= option or by
setting option_1 as shown in the following table. 

-------------------------------------------------------------------------
Input  |  ECC Level    |  Error Correction Capacity  |  Recovery Capacity
-------------------------------------------------------------------------
1      |  L (default)  |  Approx 20% of symbol       |  Approx 7%
2      |  M            |  Approx 37% of symbol       |  Approx 15%
3      |  Q            |  Approx 55% of symbol       |  Approx 25%
4      |  H            |  Approx 65% of symbol       |  Approx 30%
-------------------------------------------------------------------------

The size of the symbol can be set by using the --vers= option or setting 
option_2 to the QR Code version required (1-40). The size of symbol generated 
is shown in the table below. 

---------------------
Input  |  Symbol Size
---------------------
1      |  21 x 21
2      |  25 x 25
3      |  29 x 29
4      |  33 x 33
5      |  37 x 37
6      |  41 x 41
7      |  45 x 45
8      |  49 x 49
9      |  53 x 53
10     |  57 x 57
11     |  61 x 61
12     |  65 x 65
13     |  69 x 69
14     |  73 x 73
15     |  77 x 77
16     |  81 x 81
17     |  85 x 85
18     |  89 x 89
19     |  93 x 93
20     |  97 x 97
21     |  101 x 101
22     |  105 x 105
23     |  109 x 109
24     |  113 x 113
25     |  117 x 117
26     |  121 x 121
28     |  125 x 125
28     |  129 x 129
29     |  133 x 133
30     |  137 x 137
31     |  141 x 141
32     |  145 x 145
33     |  149 x 149
34     |  153 x 153
35     |  157 x 157
36     |  161 x 161
38     |  165 x 165
38     |  169 x 169
39     |  173 x 173
40     |  177 x 177
---------------------

The maximum capacity of a (version 40) QR Code symbol is 7089 numeric digits, 
4296 alphanumeric characters or 2953 bytes of data. QR Code symbols can also be 
used to encode GS1 data. QR Code symbols can by default encode characters in 
the Latin-1 set and Kanji characters which are members of the Shift-JIS 
encoding scheme. In addition QR Code supports using other character sets using 
the ECI mechanism. Input should usually be entered as Unicode (UTF-8) with 
conversion to Shift-JIS being carried out by Zint. A separate symbology ID can
be used to encode Health Industry Barcode (HIBC) data which adds a leading '+'
character and a modulo-49 check digit to the encoded data. 

6.6.3 Micro QR Code (ISO 18004)
-------------------------------
A miniature version of the QR Code symbol for short messages. ECC levels can be 
selected as for QR Code (above). QR Code symbols can encode characters in the 
Latin-1 set and Kanji characters which are members of the Shift-JIS encoding 
scheme. Input should be entered as a UTF-8 stream with conversion to Shift-JIS 
being carried out automatically by Zint. A preferred symbol size can be 
selected by using the --vers= option or by setting option_2 although the actual 
version used by Zint may be different if required by the input data. The table 
below shows the possible sizes: 

---------------------------------
Input  |  Version  |  Symbol Size
---------------------------------
1      |  M1       |  11 x 11
2      |  M2       |  13 x 13
3      |  M3       |  15 x 15
4      |  M4       |  17 x 17
---------------------------------

6.6.4 Maxicode (ISO 16023)
--------------------------
Developed by UPS the Maxicode symbology employs a grid of hexagons surrounding 
a 'bulls-eye' finder pattern. This symbology is designed for the identification 
of parcels. Maxicode symbols can be encoded in one of five modes. In modes 2 
and 3 Maxicode symbols are composed of two parts named the primary and 
secondary messages. The primary message consists of a structured data field 
which includes various data about the package being sent and the secondary 
message usually consists of address data in a data structure. The format of the 
primary message required by Zint is given in the following table: 

----------------------------------------------------------------------------
Characters | Meaning
----------------------------------------------------------------------------
1 - 9      | Postcode data which can consist of up to 9 digits (for mode 2) 
           |    or up to 6 alphanumeric characters (for mode 3). Remaining 
           |    unused characters should be filled with the SPACE character
           |    (ASCII 32). 
10 - 12    | Three digit country code according to ISO 3166 (see Appendix B)
13 - 15    | Three digit service code. This depends on your parcel courier. 
----------------------------------------------------------------------------

The primary message can be set at the command prompt using the --primary= switch.
The secondary message uses the normal data entry method. For example:

zint -o test.eps -b 57 --primary='999999999840012' -d 'Secondary Message Here'

When using the API the primary message must be placed in the symbol->primary 
string. The secondary is entered in the same way as described in section 5.2. 
When either of these modes is selected Zint will analyse the primary message 
and select either mode 2 or mode 3 as appropriate.

Modes 4 to 6 can be accessed using the --mode= switch or by setting option_1. 
Modes 4 to 6 do not require a primary message. For example:

zint -o test.eps -b 57 --mode=4 -d 'A MaxiCode Message in Mode 4'

Mode 6 is reserved for the maintenance of scanner hardware and should not be 
used to encode user data.

This symbology uses Latin-1 character encoding by default but also supports the 
ECI encoding mechanism. The maximum length of text which can be placed in a 
Maxicode symbol depends on the type of characters used in the text.

Example maximum data lengths are given in the table below:

-----------------------------------------------------------------------------
Mode  |  Maximum Data Lenth   |  Maximum Data Length  |  Number of Error
      |  for Capital Letters  |  for Numeric Digits   |  Correction Codewords
-----------------------------------------------------------------------------
2*    |  84                   |  126                  |  50
3*    |  84                   |  126                  |  50
4     |  93                   |  135                  |  50
5     |  77                   |  110                  |  66
6     |  93                   |  135                  |  50
-----------------------------------------------------------------------------
* - secondary only

6.6.5 Aztec Code (ISO 24778)
----------------------------
Invented by Andrew Longacre at Welch Allyn Inc in 1995 the Aztec Code symbol is 
a matrix symbol with a distinctive bulls-eye finder pattern. Zint can generate 
Compact Aztec Code (sometimes called Small Aztec Code) as well as "full-range" 
Aztec Code symbols and by default will automatically select symbol type and 
size dependent on the length of the data to be encoded. Error correction 
codewords will normally be generated to fill at least 23% of the symbol. Two 
options are available to change this behaviour:

The size of the symbol can be specified using the --ver= option or setting 
option_2 to a value between 1 and 36 according to the following table. The 
symbols marked with an asterisk (*) in the table below are "compact" symbols, 
meaning they have a smaller bulls-eye pattern at the centre of the symbol. 

---------------------
Input  |  Symbol Size
---------------------
1      |  15 x 15*
2      |  19 x 19*
3      |  23 x 23*
4      |  27 x 27*
5      |  19 x 19
6      |  23 x 23
7      |  27 x 27
8      |  31 x 31
9      |  37 x 37
10     |  41 x 41
11     |  45 x 45
12     |  49 x 49
13     |  53 x 53
14     |  57 x 57
15     |  61 x 61
16     |  67 x 67
17     |  71 x 71
18     |  75 x 75
19     |  79 x 79
20     |  83 x 83
21     |  87 x 87
22     |  91 x 91
23     |  95 x 95
24     |  101 x 101
25     |  105 x 105
26     |  109 x 109
28     |  113 x 113
28     |  117 x 117
29     |  121 x 121
30     |  125 x 125
31     |  131 x 131
32     |  135 x 135
33     |  139 x 139
34     |  143 x 143
35     |  147 x 147
36     |  151 x 151
---------------------

Note that in symbols which have a specified size the amount of error correction 
is dependent on the length of the data input and Zint will allow error 
correction capacities as low as 3 codewords.

Alternatively the amount of error correction data can be specified by use of 
the --mode= option or by setting option_1 to a value from the following table: 

----------------------------------
Mode  |  Error Correction Capacity
----------------------------------
1     |  >10% + 3 codewords
2     |  >23% + 3 codewords
3     |  >36% + 3 codewords
4     |  >50% + 3 codewords
----------------------------------

It is not possible to select both symbol size and error correction capacity for 
the same symbol. If both options are selected then the error correction 
capacity selection will be ignored. 

Aztec Code supports ECI encoding and can encode up to a maximum length of 
approximately 3823 numeric or 3067 alphabetic characters or 1914 bytes of data. 
A separate symbology ID can be used to encode Health Industry Barcode (HIBC) 
data which adds a leading '+' character and a modulo-49 check digit to the 
encoded data.

6.6.6 Aztec Runes
-----------------
A truncated version of compact Aztec Code for encoding whole integers between 0 
and 255. Includes Reed-Solomon error correction. As defined in ISO/IEC 24778 
Annex A. 

6.6.7 Code One
--------------
A matrix symbology developed by Ted Williams in 1992 which encodes data in a 
way similar to Data Matrix ECC200. Code One is able to encode the Latin-1 
character set or GS1 data. There are two types of Code One symbol - variable 
height symbols which are roughly square (versions A thought to H) and 
fixed-height versions (version S and T). These can be selected by using --vers= 
or setting option_2 as shown in the table below: 

--------------------------------------------------------------------
Input  |  Version  |  Size        |  Numeric        |  Alphanumeric
       |           |              |  Data Capacity  |  Data Capacity
--------------------------------------------------------------------
1      |  A        |  16 x 18     |  22             |  13
2      |  B        |  22 x 22     |  44             |  27
3      |  C        |  28 x 28     |  104            |  64
4      |  D        |  40 x 42     |  217            |  135
5      |  E        |  52 x 54     |  435            |  271
6      |  F        |  70 x 76     |  886            |  553
7      |  G        |  104 x 98    |  1755           |  1096
8      |  H        |  148 x 134   |  3550           |  2218
9      |  S        |  8X height   |  18             |  N/A
10     |  T        |  16X height  |  90             |  55
--------------------------------------------------------------------

Version S symbols can only encode numeric data. The width of version S and 
version T symbols is determined by the length of the input data. 

6.6.8 Grid Matrix
-----------------
By default Grid Matrix supports encoding in Latin-1 and Chinese characters 
within the GB 2312 standard set to be encoded in a checkerboard pattern. Input 
should be entered as Unicode (UTF-8) with conversion to GB 2312 being carried 
out automatically by Zint. The symbology also supports the ECI mechanism. The 
size of the symbol and the error correction capacity can be specified. If you 
specify both of these values then Zint will make a 'best-fit' attempt to 
satisfy  both conditions. The symbol size can be specified using the --ver=
option or by setting option_2, and the error correction capacity can be
specified by using the --security= option or by setting option_1 according to
the following tables: 

---------------------
Input  |  Symbol Size
---------------------
1      |  18 x 18
2      |  30 x 30
3      |  42 x 42
4      |  54 x 54
5      |  66 x 66
6      |  78 x 78
7      |  90 x 90
8      |  102 x 102
9      |  114 x 114
10     |  126 x 126
11     |  138 x 138
12     |  150 x 150
13     |  162 x 162
---------------------

----------------------------------
Mode  |  Error Correction Capacity
----------------------------------
1     |  Approximately 10%
2     |  Approximately 20%
3     |  Approximately 30%
4     |  Approximately 40%
5     |  Approximately 50%
----------------------------------

6.6.9 DotCode
-------------
DotCode uses a grid of dots in a rectangular formation to encode characters up 
to a maximum of approximately 450 characters (or 900 numeric digits). The 
symbology supports ECI encoding and GS-1 data encoding. By default Zint will 
produce a symbol which is approximately square, however the width of the symbol 
can be adjusted by using the --cols= option or by setting option_2. Outputting 
DotCode to raster images (PNG, GIF, BMP, PCX) will require setting the scale of 
the image to a larger value than the default (e.g. approx 10) for the dots to 
be plotted correctly. Approximately 33% of the resulting symbol is comprised of 
error correction codewords.

6.6.10 Han Xin Code
-------------------
Also known as Chinese Sensible Code, Han Xin is a symbology which is still 
under 
development, so it is recommended it should not yet be used for a production 
environment. The symbology is capable of encoding characters in the GB18030 
character set (up to 4-byte characters) and is also able to support the ECI 
mechanism. Han Xin does not support the encoding of GS-1 data.

The size of the symbol can be specified using the --ver= option or setting 
option_2 to a value between 1 and 84 according to the following table.

---------------------
Input  |  Symbol Size
---------------------
1      |  23 x 23
2      |  25 x 25
3      |  27 x 27
4      |  29 x 29
5      |  31 x 31
6      |  33 x 33
7      |  35 x 35
8      |  37 x 37
9      |  39 x 39
10     |  41 x 41
11     |  43 x 43
12     |  45 x 45
13     |  47 x 47
14     |  49 x 49
15     |  51 x 51
16     |  53 x 53
17     |  55 x 55
18     |  57 x 57
19     |  59 x 59
20     |  61 x 61
21     |  63 x 63
22     |  65 x 65
23     |  67 x 67
24     |  69 x 69
25     |  71 x 71
26     |  73 x 73
28     |  75 x 75
28     |  77 x 77
29     |  79 x 79
30     |  81 x 81
31     |  83 x 83
32     |  85 x 85
33     |  87 x 87
34     |  89 x 89
35     |  91 x 91
36     |  93 x 93
37     |  95 x 95
38     |  97 x 97
39     |  99 x 99
40     |  101 x 101
41     |  103 x 103
42     |  105 x 105
43     |  107 x 107
44     |  109 x 109
45     |  111 x 111
46     |  113 x 113
47     |  115 x 115
48     |  117 x 117
49     |  119 x 119
50     |  121 x 121
51     |  123 x 123
52     |  125 x 125
53     |  127 x 127
54     |  129 x 129
55     |  131 x 131
56     |  133 x 133
57     |  135 x 135
58     |  137 x 137
59     |  139 x 139
60     |  141 x 141
61     |  143 x 143
62     |  145 x 145
63     |  147 x 147
64     |  149 x 149
65     |  151 x 151
66     |  153 x 153
67     |  155 x 155
68     |  157 x 157
69     |  159 x 159
70     |  161 x 161
71     |  163 x 163
72     |  165 x 165
73     |  167 x 167
74     |  169 x 169
75     |  171 x 171
76     |  173 x 173
77     |  175 x 175
78     |  177 x 177
79     |  179 x 179
80     |  181 x 181
81     |  183 x 183
82     |  185 x 185
83     |  187 x 187
84     |  189 x 189
---------------------

There are four levels of error correction capacity available for Han Xin Code 
which can be set by using the --mode= option or by setting option_1 to a value 
from the following table:

--------------------------
Mode  |  Recovery Capacity
--------------------------
1     |  Approx 8%
2     |  Approx 15%
3     |  Approx 23%
4     |  Approx 30%
--------------------------

It is not possible to select both symbol size and error correction capacity for 
the same symbol. If both options are selected then the error correction 
capacity selection will be ignored.

6.7 Other Barcode-Like Markings
-------------------------------
6.7.1. Facing Identification Mark (FIM)
---------------------------------------
Used by the United States Postal Service (USPS), the FIM symbology is used to 
assist automated mail processing. There are only 4 valid symbols which can be 
generated using the characters A-D as shown in the table below. 

----------------------------------------------------------------------------
Code Letter  |  Usage
----------------------------------------------------------------------------
A            |  Used for courtesy reply mail and metered reply mail with a 
             |     pre-printed PostNet symbol. 
B            |  Used for business reply mail without a pre-printed zip code.
C            |  Used for business reply mail with a pre-printed zip code.
D            |  Used for Information Based Indicia (IBI) postage. 
----------------------------------------------------------------------------

6.7.2 Flattermarken
-------------------
Used for the recognition of page sequences in print-shops, the Flattermarken is 
not a true barcode symbol and requires precise knowledge of the position of the 
mark on the page. The Flattermarken system can encode any length numeric data 
and does not include a check digit. 

6.7.3 DAFT Code
---------------
This is a method for creating 4-state codes where the data encoding is provided 
by an external program. Input data should consist of the letters 'D', 'A', 'F' 
and 'T' where these refer to descender, ascender, full (ascender and descender) 
and tracker (neither ascender nor descender) respectively. All other characters 
are ignored. 

7. Legal and Version Information
================================
7.1 License
-----------
Zint, libzint and Zint Barcode Studio are Copyright © 2016 Robin Stuart. All 
historical versions are distributed under the GNU General Public License 
version 3 or later. Version 2.5 is released under a dual license: the encoding 
library is released under the BSD license whereas the GUI, Zint Barcode Studio, 
is released under the GNU General Public License version 3 or later.

Telepen is a trademark of SB Electronic Systems Ltd.

QR Code is a registered trademark of Denso Wave Incorporated.

Microsoft, Windows and the Windows logo are either registered trademarks or 
trademarks of Microsoft Corporation in the United States and/or other countries.

Linux is the registered trademark of Linus Torvalds in the U.S. and other
countries.

Zint.org.uk website design and hosting provided by Robert Elliott.

7.2 Patent Issues
-----------------
All of the code in Zint is developed using information in the public domain, 
usually freely available on the Internet. Some of the techniques used may be 
subject to patents and other intellectual property legislation. It is my belief 
that any patents involved in the technology underlying symbologies utilised by 
Zint are 'unadopted', that is the holder does not object to their methods being 
used.

Any methods patented or owned by third parties or trademarks or registered 
trademarks used within Zint or in this document are and remain the property of 
their respective owners and do not indicate endorsement or affiliation with 
those owners, companies or organisations. 

7.3 Version Information
-----------------------
v0.1 - (as Zebar) Draws UPC-A. UPC-E, EAN-8, EAN-13, Interlaced 2 of 5, 
Codabar, Code 39, Extended Code 39 and Code 93 barcodes and Add-on codes EAN-2 
and EAN-5 without parity. 13/11/2006

v0.2 - Added Code 128 (which is now the default), Code 11, Code 2 of 5, Add-on 
codes EAN-2 and EAN-5 parity and MSI/Plessey without check digit. 12/12/2006

v0.3 - Added MSI/Plessey Mod 10 check and 2 x Mod 10 check options, Telepen 
ASCII and Telepen numeric, Postnet, RM4SCC. Code has been tidied up quite a 
bit. Bind option added. 30/12/2006

v0.4 - Added barcode stacking (now stacks up to 16 barcodes) and Code16k 
(stub). 15/1/2007

v0.5 - Added Australia Post 4-State Barcodes and Pharmacode (1 and 2 track). 
4-state codes now draw with correct height/width ratio. 28/2/2007

v0.6 - Added Plessey and some derivative codes (EAN-128, Code 128 subset B, 
Auspost Reply, Auspost Routing, Auspost Redirect, ITF-14). Tidied up code 
again: separated symbologies into more files and put all lookup tables into 
arrays (much reducing the amount of code, especially for Code 39e and Code 93). 
Errors now output to stderr. Added proper input verification. Distribution now 
packs with HTML pages instead of separate README. Outputs to PNG. Outputs 
colour. User variable whitespace and border width. Box option. Fixed EAN add-on 
bug. Added whitespace and height options. Project name changed to Zint to avoid 
conflict with extant trade name. Added escape character input. 1/4/2007

v1.0 - Corrected problem with escape character codes. Supports PDF417. This 
completes the list of features I originally wanted (plus a few more), hence 
skip to version 1.0. 20/4/2007

v1.1 - Added more derivatives (Code 2 of 5 Matrix, IATA and Data Logic, 
Truncated PDF417, Deutsche Post Leitcode and Identcode, Pharmazentralnummer, 
Planet) and Flattermarken. Tidied up 2 of 5 code. 26/4/2007

v1.2 - Supports Data Matrix ECC200 (by absorption of IEC16022 code by Stefan 
Schmidt et al). Added reverse colours, FIM, MSI/Plessey Modulo 11 and Modulo 
11/10. Corrected Code 16k check digit calculation. 28/5/2007

v1.3 - Supports USPS OneCode and LOGMARS. Brought all usage information into 
one User Manual document. 13/6/2007

v1.4 - Added NVE-18 support. Corrected some problems with compilation and input 
verification. Command line option handling now uses getopt(), and all the 
switches have changed. Added –font option. 20/6/2007

v1.5 - Pulled everything together to make an API. Corrected errors with EAN-13, 
PDF417 and LOGMARS. Added EPS output. Added QR Code support using libqrencode. 
Corrected ISBN verification error. Re-compiled documentation in HTML form. Put 
in place proper error handling routines. --font option removed. Encoding is now 
done with a restructured zint_symbol structure. Added make install option and 
optional QR Code support to Makefile. Corrected minor problem with 4-State 
Codes. Restructured code into fewer source code files. Added MicroPDF417 
support. 12/8/2007

v1.5.1 - Added formatting code to EPS output of EAN and UPC symbols according 
to EN 797:1996. Checked against and, where appropriate, altered or corrected to 
comply with ISO 16388 and ISO 15417 including Latin-1 support. Altered default 
image settings, added automatic ITF border. Corrected error with USPS OneCode. 
Tidied up Code 39 quite a bit, added Mod 43 options. 3/9/2007

v1.5.2 - Added extended ASCII support to Code 16k. Corrected Code 128 error. 
Added Maxicode support by integrating code by John Lien. 26/9/2007

v1.5.3 - Made huge corrections to Maxicode support by removing and re-writing 
much of John's code. Maxicode now supports extended ASCII and modes 4, 5 and 6. 
10/10/2007

v1.5.4 - Added GS1 DataBar (Reduced Space Symbology) support. 26/11/2007

v1.5.5 - Added composite symbology support. Corrected errors with GS1-128 and

PDF417/MicroPDF417 byte processing. Transferred licence to GPL version 3. 
9/3/2008

v1.6 - Data Matrix ECC200, Maxicode and Australia Post now use common 
Reed-Solomon functions – this also fixes a bug in Maxicode error correction and 
replaces the last of the Lien code. Added PNG output for Maxicode symbols. 
Removed some useless code. Updated QR support for libqrencode v2.0.0. 22/4/2008

v1.6.1 - Major restructuring of PNG generating code: Now draws UPCA and EAN 
symbols properly and puts human readable text into the image. Also corrected 
some nasty 'never ending loop' bugs in Code 128 and check digit bugs in PostNet 
and Planet. 8/7/2008

v1.6.2 - Added KIX Code support and PNG image rotation. Corrected a bug 
affecting extended ASCII support in Code 128 and Code 16k. 28/7/2008.

v2.0 beta - Added support for Aztec Code, Codablock-F, Code 32, EAN-14 and DAFT 
Code. Rearranged symbology numbers to match Tbarcode v8. Corrected a never 
ending loop bug in EAN-128. 29/9/2008

v2.0 beta r2 - Many corrections and bugfixes. (Code 11, Code 128, EAN-128, 
Aztec Code, Codablock-F, Code 16k, Postnet, PLANET, NVE-18, PZN, Data Matrix 
ECC200, Maxicode and QR Code)

v2.0 - Made corrections to Aztec Code and tested output with bcTester. Added 
Aztec Runes, Micro QR Code and Data Matrix ECC200 ECC 000-140. Updated e-mail 
information. 18/11/2008

v2.1 - Reinstated Korea Post barcodes, harmonised bind and box options, moved 
Unicode handling into backend and added input_mode option, added size options 
to Data Matrix ECC200, added NULL character handling for Codablock-F, Code 128, 
Code 16k, Extended Code 39, Code 93, Telepen, Maxicode, Data Matrix ECC200 ECC 
200, PDF417 and MicroPDF417. Added GS1 support for Code 16k, Codablock-F and 
Aztec Code. Added scale and direct to stdout options. Rebult Data Matrix ECC200 
ECC 200 encoding algorithms to support NULL encoding and GS1 data encoding. 
31/1/2009

v2.1.1 - Minor Data Matrix ECC200 bugfix and added HIBC options. 10/2/2009

v2.1.2 - Added SVG output option. Improved Japanese character support including 
Unicode > Shift-JIS capability. Bugfixes for Data Matrix ECC200 (missing 
characters at end of string) and Codablock-F (K1/K2 check digit and row 
indicators above row 6). 1/3/2009

v2.1.3 - Many improvements to the QZint GUI which is now renamed "Zint Barcode 
Studio 0.2". Added Japanese Postal Barcode, Code 49 and Channel Code and made 
corrections to Data Matrix ECC200 (Binary mode data compression terminates too 
soon), Aztec Code (Bug when automatically resizing after removing "all 0" and 
"all 1" codewords) and Code 128 (Extended ASCII characters become corrupt). 
19/5/2009

v2.1.4 - Many stability improvements including removal of buffer overruns in 
Code 39, LOGMARS, PZN, Aztec Code and Composite CC-A. Addition of files for 
compiling on MS Windows platform - tested successfully on XP and Vista. 
19/6/2009

v2.2 - Added Code One and GS1 support in Code 49. Changed GUI binary name to 
zint-qt and brought GUI up to version 1.0. Made some minor bugfixes to Code 39, 
ITF-14, Aztec Code, Code 128 and Code 16K. Added 'rest' button to GUI. Included 
.spec file from Radist. 18/7/2009

v2.2.1 - Data encoding bugfixes for Aztec Code, Data Matrix ECC200, USPS One 
Code and PDF417. Symbol plotting bugfixes for MicroPDF417 and 2D components of 
composite symbols. Text formatting bugfix for Qt renderer and a couple of 
compiler fixes for MSVC PNG image output. 6/8/2009

v2.2.2 - A beta release previewing the new API structure. Better NULL character 
support with "nullchar" value removed. Added loading from file and sequence 
dialogs in Barcode Studio. 29/9/2009

v2.3 - Fixed problems with Micro QR Code and rebuilt QR Code support removing 
dependence on libqrencode. Improved Kanji character support for QR Code and 
Micro QR Code which now auto-detects and automatically converts to Shift-JIS. 
Added Grid Matrix symbology with Kanji character support and automatic 
conversion to GB 2312. Removed no_qr compile option. Advanced Barcode Studio 
version number to match library version number. 23/11/2009

v2.3.1 - Removed Codablock-F. Redesigned scale function so that human readable 
text and Maxicode symbols can be scaled consistently. Corrected encoding bugs 
with Code 128/Code 16k and Data Matrix ECC200 ECC 050. Added --notext option to 
CLI. 7/3/2010

v2.3.2 - Corrected many bugs in GS1 DataBar Extended thanks to the careful 
study of the code by Pablo Orduña at the PIRAmIDE project. Similarly corrected 
some bugs in Maxicode thanks to Monica Swanson at Source Technologies. Also 
minor bugfixes for ISBN and Aztec Code, and added some small features like a 
--square option in the CLI. 29/5/2010

v2.4 - Built extensions to the API for integrating with glabels with thanks to 
Sam Lown and Jim Evins. Added code optimisation and input from stdin thanks to 
Ismael Luceno. Reinstated escape character input. Simplification of Barcode 
Studio. 13/9/2010

v2.4.1 & 2.4.2 – A whole host of bugfixes including correction of ECC routines 
for Code-1 and addition of batch processing at the command line. 19/4/2011 &
4/5/2011

v2.4.3 - Includes minor bugfixes 16/5/2011

v2.5 – Support for DotCode and Han Xin code. ECI code processing. Output to 
BMP, GIF and PCX. Added bold text option. Many minor bugfixes and improvements. 
(Due for release November 2016).

7.4 Sources of Information
--------------------------
Below is a list of some of the sources used in rough chronological order:

Nick Johnson's Barcode Specifications
Bar Code 1 Specification Source Page
SB Electronic Systems Telepen website
Pharmacode specifications from Laetus
Morovia RM4SCC specification
Austalia Post's 'A Guide to Printing the 4-State Barcode' and bcsample source 
   code
Plessey algorithm from GNU-Barcode v0.98 by Leonid A. Broukhis
GS1 General Specifications v 8.0 Issue 2
PNG: The Definitive Guide and wpng source code by Greg Reolofs
PDF417 specification and pdf417 source code by Grand Zebu
Barcode Reference, TBarCode/X User Documentation and TBarCode/X demonstration 
   program from Tec-It
IEC16022 source code by Stefan Schmidt et al
United States Postal Service Specification USPS-B-3200
Adobe Systems Incorporated Encapsulated PostScript File Format Specification
BSI Online Library
Libdmtx Data Matrix ECC200 decoding library

7.5 Standard Compliance
-----------------------
Zint was developed to provide compliance with the following British and 
international standards: 

> BS EN 797:1996 Bar coding - Symbology specifications - 'EAN/UPC' 
> BS EN 798:1996 Bar coding - Symbology specifications - 'Codabar' 
> ISO/IEC 12323:2005 AIDC technologies - Symbology specifications - Code 16K 
> ISO/IEC 15417:2007 Information technology - Automatic identification and data 
     capture techniques - Code 128 bar code symbology specification 
> ISO/IEC 15438:20062015 Information technology - Automatic identification and 
     data capture techniques - PDF417 bar code symbology specification 
> ISO/IEC 16022:2006 Information technology - Automatic identification and data 
     capture techniques - Data Matrix ECC200 bar code symbology specification 
> ISO/IEC 16023:2000 Information technology - International symbology 
     specification – Maxicode 
> ISO/IEC 16388:2007 Information technology - Automatic identification and data 
     capture techniques - Code 39 bar code symbology specification 
> ISO/IEC 18004:2015 Information technology - Automatic identification and data 
     capture techniques - QR Code bar code symbology specification 
> ISO/IEC 24723:2010 Information technology - Automatic identification and data 
     capture techniques - GS1 Composite bar code symbology specification 
> ISO/IEC 24724:2011 Information technology - Automatic identification and data 
     capture techniques - GS1 DataBar bar code symbology specification 
> ISO/IEC 24728:2006 Information technology - Automatic identification and data 
     capture techniques - MicroPDF417 bar code symbology specification 
> ISO/IEC 24778:2008 Information technology - Automatic identification and data 
     capture techniques - Aztec Code bar code symbology specification 
> Uniform Symbology Specification Code One (AIM Inc., 1994) 
> ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code 
> ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 
> ANSI/HIBC 2.3-2009 - The Health Industry Bar Code (HIBC) Supplier Labeling 
     Standard 
> AIM ISS-X-24 - Uniform Symbology Specification Codablock F
> AIMD013 (v 1.34a) – Information technology – Automaic identification and data 
     capture techniques – Bar code symbology specification – DotCode (Revised 
     19th Feb 2009)
> AIMD014 (v 1.63) - Information technology, Automatic identification and data 
     capture techniques - Bar code symbology specification - Grid Matrix 
     (Released 9th Dec 2008) 
> AIMD-015:2010 (v 0.8) – DRAFT Bar code symbology specification – Han Xin Code 
     (Revised 25th March 2010)
> GS1 General Specifications Version 8.0 
> AIM ITS/04-001 International Technical Standard – Extended Channel 
     Interpretations Part 1: Identification Schemes and Protocol (Released 24th 
     May 2004)
> AIM ITS/04-023 International Technical Standard – Extended Channel 
     Interpretations Part 3: Register (Released 15th July 2004)
     
A. Character Encoding
=====================
This section is intended as a quick reference to the character sets used by 
Zint. All symbologies use standard ASCII input as shown in section A.1, but 
some support extended character support as shown in the subsequent section.

A.1 ASCII Standard
------------------
The ubiquitous ASCII standard is well known to most computer users. It's 
reproduced here for reference.

-------------------------------------------------------------
Hex |  0     |  1    |  2      |  3  |  4  |  5  |  6  |  7
-------------------------------------------------------------
0   |  NULL  |  DLE  |  SPACE  |  0  |  @  |  P  |  `  |  p
1   |  SOH   |  DC1  |  !      |  1  |  A  |  Q  |  a  |  q
2   |  STX   |  DC2  |  "      |  2  |  B  |  R  |  b  |  r
3   |  ETX   |  DC3  |  #      |  3  |  C  |  S  |  c  |  s
4   |  EOT   |  DC4  |  $      |  4  |  D  |  T  |  d  |  t
5   |  ENQ   |  NAK  |  %      |  5  |  E  |  U  |  e  |  u
6   |  ACK   |  SYN  |  &      |  6  |  F  |  V  |  f  |  v
7   |  BEL   |  ETB  |  '      |  7  |  G  |  W  |  g  |  w
8   |  BS    |  CAN  |  (      |  8  |  H  |  X  |  h  |  x
9   |  TAB   |  EM   |  )      |  9  |  I  |  Y  |  i  |  y
A   |  LF    |  SUB  |  *      |  :  |  J  |  Z  |  j  |  z
B   |  VT    |  ESC  |  +      |  ;  |  K  |  [  |  k  |  {
C   |  FF    |  FS   |  ,      |  <  |  L  |  \  |  l  |  |
D   |  CR    |  GS   |  -      |  =  |  M  |  ]  |  m  |  }
E   |  SO    |  RS   |  .      |  >  |  N  |  ^  |  n  |  ~
F   |  SI    |  US   |  /      |  ?  |  O  |  _  |  o  |  DEL
-------------------------------------------------------------

A.2 Latin Alphabet No 1 (ISO 8859-1)
------------------------------------
A common extension to the ASCII standard, Latin-1 is used to expand the range 
of Code 128, PDF417 and other symbols. Input strings should be in Unicode 
format 

------------------------------------------------------
Hex |  8  |  9  |  A      |  B  |  C  |  D  |  E  |  F
------------------------------------------------------
0   |     |     |  NBSP   |  °  |  À  |  Ð  |  à  |  ð
1   |     |     |  ¡      |  ±  |  Á  |  Ñ  |  á  |  ñ
2   |     |     |  ¢      |  ²  |  Â  |  Ò  |  â  |  ò
3   |     |     |  £      |  ³  |  Ã  |  Ó  |  ã  |  ó
4   |     |     |  ¤      |  ´  |  Ä  |  Ô  |  ä  |  ô
5   |     |     |  ¥      |  μ  |  Å  |  Õ  |  å  |  õ
6   |     |     |  ¦      |  ¶  |  Æ  |  Ö  |  æ  |  ö
7   |     |     |  §      |  ·  |  Ç  |  ×  |  ç  |  ÷
8   |     |     |  ¨      |  ¸  |  È  |  Ø  |  è  |  ø
9   |     |     |  ©      |  ¹  |  É  |  Ù  |  é  |  ù
A   |     |     |  ª      |  º  |  Ê  |  Ú  |  ê  |  ú
B   |     |     |  «      |  »  |  Ë  |  Û  |  ë  |  û
C   |     |     |  ¬      |  ¼  |  Ì  |  Ü  |  ì  |  ü
D   |     |     |  SHY    |  ½  |  Í  |  Ý  |  í  |  ý
E   |     |     |  ®      |  ¾  |  Î  |  Þ  |  î  |  þ
F   |     |     |  ¯      |  ¿  |  Ï  |  ß  |  î  |  ÿ
------------------------------------------------------

B. Three Digit Country Codes (ISO 3166)
---------------------------------------
Below are some of the three digit country codes (in right-hand column) as 
determined by ISO 3166 for use with Maxicode symbols. 

Country                                         A 2     A 3     Number
----------------------------------------------------------------------
AALAND ISLANDS                                  AX      ALA     248
AFGHANISTAN                                     AF      AFG     004
ALBANIA                                         AL      ALB     008
ALGERIA                                         DZ      DZA     012
AMERICAN SAMOA                                  AS      ASM     016
ANDORRA                                         AD      AND     020
ANGOLA                                          AO      AGO     024
ANGUILLA                                        AI      AIA     660
ANTARCTICA                                      AQ      ATA     010
ANTIGUA AND BARBUDA                             AG      ATG     028
ARGENTINA                                       AR      ARG     032
ARMENIA                                         AM      ARM     051  
ARUBA                                           AW      ABW     533
AUSTRALIA                                       AU      AUS     036
AUSTRIA                                         AT      AUT     040
AZERBAIJAN                                      AZ      AZE     031  
BAHAMAS                                         BS      BHS     044
BAHRAIN                                         BH      BHR     048
BANGLADESH                                      BD      BGD     050
BARBADOS                                        BB      BRB     052
BELARUS                                         BY      BLR     112  
BELGIUM                                         BE      BEL     056
BELIZE                                          BZ      BLZ     084
BENIN                                           BJ      BEN     204
BERMUDA                                         BM      BMU     060
BHUTAN                                          BT      BTN     064
BOLIVIA                                         BO      BOL     068
BOSNIA AND HERZEGOWINA                          BA      BIH     070
BOTSWANA                                        BW      BWA     072
BOUVET ISLAND                                   BV      BVT     074
BRAZIL                                          BR      BRA     076
BRITISH INDIAN OCEAN TERRITORY                  IO      IOT     086
BRUNEI DARUSSALAM                               BN      BRN     096
BULGARIA                                        BG      BGR     100
BURKINA FASO                                    BF      BFA     854
BURUNDI                                         BI      BDI     108
CAMBODIA                                        KH      KHM     116
CAMEROON                                        CM      CMR     120
CANADA                                          CA      CAN     124
CAPE VERDE                                      CV      CPV     132
CAYMAN ISLANDS                                  KY      CYM     136
CENTRAL AFRICAN REPUBLIC                        CF      CAF     140
CHAD                                            TD      TCD     148
CHILE                                           CL      CHL     152
CHINA                                           CN      CHN     156
CHRISTMAS ISLAND                                CX      CXR     162
COCOS (KEELING) ISLANDS                         CC      CCK     166
COLOMBIA                                        CO      COL     170
COMOROS                                         KM      COM     174
CONGO, Democratic Republic of (was Zaire)       CD      COD     180
CONGO, Republic of                              CG      COG     178
COOK ISLANDS                                    CK      COK     184
COSTA RICA                                      CR      CRI     188
COTE D'IVOIRE                                   CI      CIV     384
CROATIA (local name: Hrvatska)                  HR      HRV     191      
CUBA                                            CU      CUB     192
CYPRUS                                          CY      CYP     196
CZECH REPUBLIC                                  CZ      CZE     203  
DENMARK                                         DK      DNK     208
DJIBOUTI                                        DJ      DJI     262
DOMINICA                                        DM      DMA     212
DOMINICAN REPUBLIC                              DO      DOM     214
ECUADOR                                         EC      ECU     218
EGYPT                                           EG      EGY     818
EL SALVADOR                                     SV      SLV     222
EQUATORIAL GUINEA                               GQ      GNQ     226
ERITREA                                         ER      ERI     232
ESTONIA                                         EE      EST     233  
ETHIOPIA                                        ET      ETH     231
FALKLAND ISLANDS (MALVINAS)                     FK      FLK     238
FAROE ISLANDS                                   FO      FRO     234
FIJI                                            FJ      FJI     242
FINLAND                                         FI      FIN     246
FRANCE                                          FR      FRA     250
FRENCH GUIANA                                   GF      GUF     254
FRENCH POLYNESIA                                PF      PYF     258
FRENCH SOUTHERN TERRITORIES                     TF      ATF     260
GABON                                           GA      GAB     266
GAMBIA                                          GM      GMB     270
GEORGIA                                         GE      GEO     268  
GERMANY                                         DE      DEU     276
GHANA                                           GH      GHA     288
GIBRALTAR                                       GI      GIB     292
GREECE                                          GR      GRC     300
GREENLAND                                       GL      GRL     304
GRENADA                                         GD      GRD     308
GUADELOUPE                                      GP      GLP     312
GUAM                                            GU      GUM     316
GUATEMALA                                       GT      GTM     320
GUINEA                                          GN      GIN     324
GUINEA-BISSAU                                   GW      GNB     624
GUYANA                                          GY      GUY     328
HAITI                                           HT      HTI     332
HEARD AND MC DONALD ISLANDS                     HM      HMD     334
HONDURAS                                        HN      HND     340
HONG KONG                                       HK      HKG     344
HUNGARY                                         HU      HUN     348
ICELAND                                         IS      ISL     352
INDIA                                           IN      IND     356
INDONESIA                                       ID      IDN     360
IRAN (ISLAMIC REPUBLIC OF)                      IR      IRN     364
IRAQ                                            IQ      IRQ     368
IRELAND                                         IE      IRL     372
ISRAEL                                          IL      ISR     376
ITALY                                           IT      ITA     380
JAMAICA                                         JM      JAM     388
JAPAN                                           JP      JPN     392
JORDAN                                          JO      JOR     400
KAZAKHSTAN                                      KZ      KAZ     398  
KENYA                                           KE      KEN     404
KIRIBATI                                        KI      KIR     296
KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF          KP      PRK     408
KOREA, REPUBLIC OF                              KR      KOR     410
KUWAIT                                          KW      KWT     414
KYRGYZSTAN                                      KG      KGZ     417  
LAO PEOPLE'S DEMOCRATIC REPUBLIC                LA      LAO     418
LATVIA                                          LV      LVA     428  
LEBANON                                         LB      LBN     422
LESOTHO                                         LS      LSO     426
LIBERIA                                         LR      LBR     430
LIBYAN ARAB JAMAHIRIYA                          LY      LBY     434
LIECHTENSTEIN                                   LI      LIE     438
LITHUANIA                                       LT      LTU     440  
LUXEMBOURG                                      LU      LUX     442
MACAU                                           MO      MAC     446
MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF      MK      MKD     807 
MADAGASCAR                                      MG      MDG     450
MALAWI                                          MW      MWI     454
MALAYSIA                                        MY      MYS     458
MALDIVES                                        MV      MDV     462
MALI                                            ML      MLI     466
MALTA                                           MT      MLT     470
MARSHALL ISLANDS                                MH      MHL     584
MARTINIQUE                                      MQ      MTQ     474
MAURITANIA                                      MR      MRT     478
MAURITIUS                                       MU      MUS     480
MAYOTTE                                         YT      MYT     175  
MEXICO                                          MX      MEX     484
MICRONESIA, FEDERATED STATES OF                 FM      FSM     583
MOLDOVA, REPUBLIC OF                            MD      MDA     498  
MONACO                                          MC      MCO     492
MONGOLIA                                        MN      MNG     496
MONTSERRAT                                      MS      MSR     500
MOROCCO                                         MA      MAR     504
MOZAMBIQUE                                      MZ      MOZ     508
MYANMAR                                         MM      MMR     104
NAMIBIA                                         NA      NAM     516
NAURU                                           NR      NRU     520
NEPAL                                           NP      NPL     524
NETHERLANDS                                     NL      NLD     528
NETHERLANDS ANTILLES                            AN      ANT     530
NEW CALEDONIA                                   NC      NCL     540
NEW ZEALAND                                     NZ      NZL     554
NICARAGUA                                       NI      NIC     558
NIGER                                           NE      NER     562
NIGERIA                                         NG      NGA     566
NIUE                                            NU      NIU     570
NORFOLK ISLAND                                  NF      NFK     574
NORTHERN MARIANA ISLANDS                        MP      MNP     580
NORWAY                                          NO      NOR     578
OMAN                                            OM      OMN     512
PAKISTAN                                        PK      PAK     586
PALAU                                           PW      PLW     585
PALESTINIAN TERRITORY, Occupied                 PS      PSE     275
PANAMA                                          PA      PAN     591
PAPUA NEW GUINEA                                PG      PNG     598
PARAGUAY                                        PY      PRY     600
PERU                                            PE      PER     604
PHILIPPINES                                     PH      PHL     608
PITCAIRN                                        PN      PCN     612
POLAND                                          PL      POL     616
PORTUGAL                                        PT      PRT     620
PUERTO RICO                                     PR      PRI     630
QATAR                                           QA      QAT     634
REUNION                                         RE      REU     638
ROMANIA                                         RO      ROU     642
RUSSIAN FEDERATION                              RU      RUS     643
RWANDA                                          RW      RWA     646
SAINT HELENA                                    SH      SHN     654
SAINT KITTS AND NEVIS                           KN      KNA     659
SAINT LUCIA                                     LC      LCA     662
SAINT PIERRE AND MIQUELON                       PM      SPM     666
SAINT VINCENT AND THE GRENADINES                VC      VCT     670
SAMOA                                           WS      WSM     882
SAN MARINO                                      SM      SMR     674
SAO TOME AND PRINCIPE                           ST      STP     678
SAUDI ARABIA                                    SA      SAU     682
SENEGAL                                         SN      SEN     686
SERBIA AND MONTENEGRO                           CS      SCG     891
SEYCHELLES                                      SC      SYC     690
SIERRA LEONE                                    SL      SLE     694
SINGAPORE                                       SG      SGP     702
SLOVAKIA                                        SK      SVK     703  
SLOVENIA                                        SI      SVN     705  
SOLOMON ISLANDS                                 SB      SLB     090
SOMALIA                                         SO      SOM     706
SOUTH AFRICA                                    ZA      ZAF     710
SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS    GS      SGS     239
SPAIN                                           ES      ESP     724
SRI LANKA                                       LK      LKA     144
SUDAN                                           SD      SDN     736
SURINAME                                        SR      SUR     740
SVALBARD AND JAN MAYEN ISLANDS                  SJ      SJM     744
SWAZILAND                                       SZ      SWZ     748
SWEDEN                                          SE      SWE     752
SWITZERLAND                                     CH      CHE     756
SYRIAN ARAB REPUBLIC                            SY      SYR     760
TAIWAN                                          TW      TWN     158
TAJIKISTAN                                      TJ      TJK     762  
TANZANIA, UNITED REPUBLIC OF                    TZ      TZA     834
THAILAND                                        TH      THA     764
TIMOR-LESTE                                     TL      TLS     626
TOGO                                            TG      TGO     768
TOKELAU                                         TK      TKL     772
TONGA                                           TO      TON     776
TRINIDAD AND TOBAGO                             TT      TTO     780
TUNISIA                                         TN      TUN     788
TURKEY                                          TR      TUR     792
TURKMENISTAN                                    TM      TKM     795  
TURKS AND CAICOS ISLANDS                        TC      TCA     796
TUVALU                                          TV      TUV     798
UGANDA                                          UG      UGA     800
UKRAINE                                         UA      UKR     804
UNITED ARAB EMIRATES                            AE      ARE     784
UNITED KINGDOM                                  GB      GBR     826
UNITED STATES                                   US      USA     840
UNITED STATES MINOR OUTLYING ISLANDS            UM      UMI     581
URUGUAY                                         UY      URY     858
UZBEKISTAN                                      UZ      UZB     860  
VANUATU                                         VU      VUT     548
VATICAN CITY STATE (HOLY SEE)                   VA      VAT     336
VENEZUELA                                       VE      VEN     862
VIET NAM                                        VN      VNM     704
VIRGIN ISLANDS (BRITISH)                        VG      VGB     092
VIRGIN ISLANDS (U.S.)                           VI      VIR     850
WALLIS AND FUTUNA ISLANDS                       WF      WLF     876
WESTERN SAHARA                                  EH      ESH     732
YEMEN                                           YE      YEM     887
ZAMBIA                                          ZM      ZMB     894
ZIMBABWE                                        ZW      ZWE     716

C. GS1 General Specification
----------------------------
The GS1 General Specification defines a global standard for encoding data about 
products. Data is encoded as a series of number pairs where the first number, 
usually shown in (brackets) is an application identifier (AI), and the second 
is a formatted representation of the data. For example (21)6773 can be read as 
"Serial Number 6773" where the AI (21) signifies that the data is a serial 
number. Note that when using Zint AI data is entered using [square] brackets. 
This allows rounded brackets to be included in the data which is allowed by the 
specification. When the barcode symbol is generated these square brackets are 
replaced by rounded brackets in any text displayed. A list of valid AI numbers 
is given below. 

C.1 Application Identifiers [1]
---------------------------
00   Serial Shipping Container Code (SSCC)
01   Global Trade Item Number (GTIN)
02   # of containers
10   Batch Number
11   Production Date
13   Packaging Date
15   Sell by Date (Quality Control)
17   Expiration Date
20   Product Variant
21   Serial Number
22   HIBCC Quantity, Date, Batch and Link
23x  Lot Number
240  Additional Product Identification
250  Second Serial Number
30   Quantity Each
310y Product Net Weight in kg
311y Product Length/1st Dimension, in meters
312y Product Width/Diameter/2nd Dimension, in meters
313y Product Depth/Thickness/3rd Dimension, in meters
314y Product Area, in square meters
315y Product Volume, in liters
316y product Volume, in cubic meters
320y Product Net Weight, in pounds
321y Product Length/1st Dimension, in inches
322y Product Length/1st Dimension, in feet
323y Product Length/1st Dimension, in yards
324y Product Width/Diameter/2nd Dimension, in inches
325y Product Width/Diameter/2nd Dimension, in feet
326y Product Width/Diameter/2nd Dimension, in yards
327y Product Depth/Thickness/3rd Dimension, in inches
328y Product Depth/Thickness/3rd Dimension, in feet
329y Product Depth/Thickness/3rd Dimension, in yards
330y Container Gross Weight (kg)
331y Container Length/1st Dimension (Meters)
332y Container Width/Diameter/2nd Dimension (Meters)
333y Container Depth/Thickness/3rd Dimension (Meters)
334y Container Area (Square Meters)
335y Container Gross Volume (Liters)
336y Container Gross Volume (Cubic Meters)
340y Container Gross Weight (Pounds)
341y Container Length/1st Dimension, in inches
342y Container Length/1st Dimension, in feet
343y Container Length/1st Dimension in, in yards
344y Container Width/Diameter/2nd Dimension, in inches
345y Container Width/Diameter/2nd Dimension, in feet
346y Container Width/Diameter/2nd Dimension, in yards
347y Container Depth/Thickness/Height/3rd Dimension, in inches
348y Container Depth/Thickness/Height/3rd Dimension, in feet
349y Container Depth/Thickness/Height/3rd Dimension, in yards
350y Product Area (Square Inches)
351y Product Area (Square Feet)
352y Product Area (Square Yards)
353y Container Area (Square Inches)
354y Container Area (Square Feet)
355y Container Area (Suqare Yards)
356y Net Weight (Troy Ounces)
360y Product Volume (Quarts)
361y Product Volume (Gallons)
362y Container Gross Volume (Quarts)
363y Container Gross Volume (Gallons)
364y Product Volume (Cubic Inches)
365y Product Volume (Cubic Feet)
366y Product Volume (Cubic Yards)
367y Container Gross Volume (Cubic Inches)
368y Container Gross Volume (Cubic Feet)
369y Container Gross Volume (Cubic Yards)
37   Number of Units Contained
400  Customer Purchase Order Number
410  Ship To/Deliver To Location Code (Global Location Number)
411  Bill To/Invoice Location Code (Global Location Number)
412  Purchase From Location Code (Global Location Number)
420  Ship To/Deliver To Postal Code (Single Postal Authority)
421  Ship To/Deliver To Postal Code (Multiple Postal Authority)
8001 Roll Products - Width/Length/Core Diameter
8002 Electronic Serial Number (ESN) for Cellular Phone
8003 Global Returnable Asset Identifier
8004 Global Individual Asset Identifier
8005 Price per Unit of Measure
8100 Coupon Extended Code: Number System and Offer
8101 Coupon Extended Code: Number System, Offer, End of Offer
8102 Coupon Extended Code: Number System preceded by 090 Mutually Agreed 
     Between Trading Partners
91   Internal Company Codes
92   Internal Company Codes
93   Internal Company Codes
94   Internal Company Codes
95   Internal Company Codes
96   Internal Company Codes
97   Internal Company Codes
98   Internal Company Codes
99   Internal Company Codes

C.2 Fixed Length Fields
-----------------------
The GS1 Specification requires that some of the data to be encoded fits a 
standard length field. Zint will generate an error if the correct data lengths 
are not entered. The following table details which AIs have fixed length data 
fields and how long the data should be for each: 

------------------------------------
Application  |  Number of Characters
Identifier   |  (AI and Data Field)
------------------------------------
00           |  20
01           |  16
02           |  16
03           |  16
04           |  18
11           |  8
12           |  8
13           |  8
14           |  8
15           |  8
16           |  8
17           |  8
18           |  8
19           |  8
20           |  4
31           |  10
32           |  10
33           |  10
34           |  10
35           |  10
36           |  10
41           |  16
------------------------------------

[1] This information taken from Wikipedia (http://en.wikipedia.org/wiki/GS1) and 
used under the terms of the GNU Free Documentation License . 
Added jni/zint/frontend/isotest.sh.






















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
zint -o aimbc6_fig1.gif -b 24 -d "MULTIPLE ROWS IN CODE 49"
zint -o aimbc6_fig3.gif -b 24 -d "EXAMPLE 2"
zint -o aimbc6_figb1.gif -b 24 -d "EXAMPLE 2"
zint -o aimbc12_fig1.gif -b 140 -d 1234
zint -o aimbc12_fige1.gif -b 140 -d 1000000
zint -o aimbc12_figf1a.gif -b 140 -d 00
zint -o aimbc12_figf1b.gif -b 140 -d 000
zint -o aimbc12_figf1c.gif -b 140 -d 0000
zint -o aimbc12_figf1d.gif -b 140 -d 00000
zint -o aimbc12_figf1e.gif -b 140 -d 000000
zint -o aimbc12_figf1f.gif -b 140 -d 0000000
zint -o aimbc12_figf1g.gif -b 140 -d 02
zint -o aimbc12_figf1h.gif -b 140 -d 004
zint -o aimbc12_figf1i.gif -b 140 -d 0005
zint -o aimbc12_figf1j.gif -b 140 -d 00010
zint -o aimbc12_figf1k.gif -b 140 -d 000100
zint -o aimbc12_figf1l.gif -b 140 -d 0001000
zint -o aimbc12_figf1m.gif -b 140 -d 05
zint -o aimbc12_figf1n.gif -b 140 -d 007
zint -o aimbc12_figf1o.gif -b 140 -d 0010
zint -o aimbc12_figf1p.gif -b 140 -d 00100
zint -o aimbc12_figf1q.gif -b 140 -d 001000
zint -o aimbc12_figf1r.gif -b 140 -d 0010000
zint -o aimbc12_figf1s.gif -b 140 -d 08
zint -o aimbc12_figf1t.gif -b 140 -d 010
zint -o aimbc12_figf1u.gif -b 140 -d 0100
zint -o aimbc12_figf1v.gif -b 140 -d 01000
zint -o aimbc12_figf1w.gif -b 140 -d 010000
zint -o aimbc12_figf1x.gif -b 140 -d 0100000
zint -o aimbc12_figf1y.gif -b 140 -d 10
zint -o aimbc12_figf1z.gif -b 140 -d 100
zint -o aimbc12_figf1aa.gif -b 140 -d 1000
zint -o aimbc12_figf1ab.gif -b 140 -d 10000
zint -o aimbc12_figf1ac.gif -b 140 -d 100000
zint -o aimbc12_figf1ad.gif -b 140 -d 1000000
zint -o aimbc12_figf1ae.gif -b 140 -d 26
zint -o aimbc12_figf1af.gif -b 140 -d 292
zint -o aimbc12_figf1ag.gif -b 140 -d 3493
zint -o aimbc12_figf1ah.gif -b 140 -d 44072
zint -o aimbc12_figf1ai.gif -b 140 -d 576688
zint -o aimbc12_figf1aj.gif -b 140 -d 7742862
zint -o aim_cbf_fig1.gif -b 74 -d "CODABLOCK F 34567890123456789010040digit"
zint -o aimd013_fig1a.gif -b 115 --scale=10 --cols=51 --gs1 -d "[17]070620[10]ABC123456"
zint -o aimd013_fig1b.gif -b 115 --scale=10 --cols=23 --gs1 -d "[17]070620[10]ABC123456"
zint -o aimd013_fig4.gif -b 115 --scale=10 --gs1 -d "[17]070620[10]ABC123456"
zint -o aimd013_fig9.gif -b 115 --scale=10 -d "Dots can be Square!"
zint -o aimd014_fig1.gif -b 142 -d "Grid Matrix"
zint -o aimd014_fig12.gif -b 142 -d "Grid Matrix"
zint -o aimd014_figd1.gif -b 142 -d "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738"
zint -o en797_fig1.gif -b 13 -d 501234567890
zint -o en797_fig2.gif -b 13 -d 2012345
zint -o en797_fig3.gif -b 34 -d 01234567890
zint -o en797_fig4.gif -b 37 -d 0012345
zint -o en797_fig5.gif -b 13 -d 501234567890+12
zint -o en797_fig6.gif -b 13 -d 501234567890+86104
zint -o en798_fig1.gif -b 18 -d A37859B
zint -o en12323_fig3.gif -b 23 -d "ab0123456789"
zint -o iso15417_fig1.gif -b 20 -d AIM
zint -o iso15438_fig1.gif -b 55 -d "PDF417 Symbology Standard"
zint -o iso16388_fig1.gif -b 8 -d 1A
zint -o iso16022_fig1.gif -b 71 -d "A1B2C3D4E5F6G7H8I9J0K1L2"
zint -o iso16022_figo2.gif -b 71 -d "123456"
zint -o iso16022_figr1.gif -b 71 -d "30Q324343430794<OQQ"
zint -o iso16023_fig2.gif -b 57 --mode=4 -d "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL..."
zint -o iso16023_figb2.gif -b 57 --mode=2 --primary="152382802840001" -d "[)>\R01\G961Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G634 ALPHA DR\GPITTSBURGH\GPA\R\E"
zint -o iso16023_figh1.gif -b 57 --mode=4 -d "Maxi Code (19 chars)"
zint -o iso18004_fig1.gif -b 58 -d "QR Code Symbol"
zint -o iso18004_fig2.gif -b 97 -d "01234567"
zint -o iso18004_fig29.gif -b 58 -d "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
zint -o iso18004_figi2.gif -b 58 -d "01234567"
zint -o iso18004_figi4.gif -b 97 -d "01234567"
zint -o iso24723_fig1.gif -b 133 --primary=1311234567890 -d "[17]010615[10]A123456"
zint -o iso24723_fig2.gif -b 131 --mode=3 --primary="[01]93812345678901" -d "[10]ABCD123456[410]3898765432108"
zint -o iso24723_fig3.gif -b 136 --mode=1 --primary=121230 -d "[15]021231"
zint -o iso24723_fig4.gif -b 130 --mode=1 --primary=1234567 -d "[21]A12345678"
zint -o iso24723_fig5.gif -b 130 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
zint -o iso24723_fig6.gif -b 137 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o iso24723_fig7.gif -b 133 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
zint -o iso24723_fig8.gif -b 132 --mode=1 --primary=361234567890 -d "[11]990102"
zint -o iso24723_fig9.gif -b 134 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
zint -o iso24723_fig10.gif -b 139 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
zint -o iso24723_fig11.gif -b 131 --mode=1 --primary="[01]03212345678906" -d "[21]A1B2C3D4E5F6G7H8"
zint -o iso24723_fig12.gif -b 131 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
zint -o iso24724_fig1.gif -b 29 -d 2001234567890
zint -o iso24724_fig2.gif -b 29 -d 0441234567890
zint -o iso24724_fig4.gif -b 29 --height=11 -d 0001234567890
zint -o iso24724_fig5.gif -b 79 -d 0001234567890
zint -o iso24724_fig6.gif -b 80 -d 0003456789012
zint -o iso24724_fig7.gif -b 30 -d 1501234567890
zint -o iso24724_fig8.gif -b 30 -d 0031234567890
zint -o iso24724_fig10.gif -b 31 -d "[01]98898765432106[3202]012345[15]991231"
zint -o iso24724_fig11.gif -b 31 -d "[01]90012345678903[3103]001750"
zint -o iso24724_fig12.gif -b 81 -d "[01]98898765432106[3202]012345[15]991231"
zint -o iso24724_fig13.gif -b 81 -d "[01]95012345678903[3103]000123"
zint -o iso24724_figf2.gif -b 30 -d 0009876543210
zint -o iso24724_figr3.gif -b 31 -d "[10]12A"
zint -o iso24728_fig1a.gif -b 84 --cols=1 -d "ABCDEFGHIJKLMNOPQRSTUV"
zint -o iso24728_fig1b.gif -b 84 --cols=2 -d "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCD"
zint -o iso24728_fig1c.gif -b 84 --cols=3 -d "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN"
zint -o iso24728_fig1d.gif -b 84 --cols=4 -d "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB"
zint -o iso24778_figa1a.gif -b 128 -d 0
zint -o iso24778_figa1b.gif -b 128 -d 25
zint -o iso24778_figa1c.gif -b 128 -d 125
zint -o iso24778_figa1d.gif -b 128 -d 255
zint -o iso24778_figg2.gif -b 92 -d "Code 2D!"
zint -o iso24778_figi1a.gif -b 92 -d "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
zint -o iso24778_figi1b.gif -b 92 -d "3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"
Changes to jni/zint/frontend/main.c.
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82



83
84
85
86
87
88

89

90
91
92

93
94

95

96
97
98
99
100





101
102





103
104
105
106
107


108
109

























110
111
112
113
114
115
116

#ifdef _MSC_VER
#include <malloc.h>
#endif

/* Print list of supported symbologies */
void types(void) {
    printf( " 1: Code 11           51: Pharma One-Track         90: KIX Code\n"

            " 2: Standard 2of5     52: PZN                      92: Aztec Code\n"
            " 3: Interleaved 2of5  53: Pharma Two-Track         93: DAFT Code\n"
            " 4: IATA 2of5         55: PDF417                   97: Micro QR Code\n"
            " 6: Data Logic        56: PDF417 Trunc             98: HIBC Code 128\n"
            " 7: Industrial 2of5   57: Maxicode                 99: HIBC Code 39\n"
            " 8: Code 39           58: QR Code                 102: HIBC Data Matrix\n"
            " 9: Extended Code 39  60: Code 128-B              104: HIBC QR Code\n"
            "13: EAN               63: AP Standard Customer    106: HIBC PDF417\n"
            "16: GS1-128           66: AP Reply Paid           108: HIBC MicroPDF417\n"
            "18: Codabar           67: AP Routing              112: HIBC Aztec Code\n"
            "20: Code 128          68: AP Redirection          128: Aztec Runes\n"
            "21: Leitcode          69: ISBN                    129: Code 23\n"
            "22: Identcode         70: RM4SCC                  130: Comp EAN\n"
            "23: Code 16k          71: Data Matrix             131: Comp GS1-128\n"
            "24: Code 49           72: EAN-14                  132: Comp DataBar Omni\n"

            "25: Code 93           75: NVE-18                  133: Comp DataBar Ltd\n"
            "28: Flattermarken     76: Japanese Post           134: Comp DataBar ExpOm\n"
            "29: GS1 DataBar Omni  77: Korea Post              135: Comp UPC-A\n"
            "30: GS1 DataBar Ltd   79: GS1 DataBar Stack       136: Comp UPC-E\n"
            "31: GS1 DataBar ExpOm 80: GS1 DataBar Stack Omni  137: Comp DataBar Stack\n"
            "32: Telepen Alpha     81: GS1 DataBar ESO         138: Comp DataBar Stack Omni\n"
            "34: UPC-A             82: Planet                  139: Comp DataBar ESO\n"
            "37: UPC-E             84: MicroPDF                140: Channel Code\n"
            "40: Postnet           85: USPS OneCode            141: Code One\n"
            "47: MSI Plessey       86: UK Plessey              142: Grid Matrix\n"

            "49: FIM               87: Telepen Numeric\n"
            "50: Logmars           89: ITF-14\n"
            );
}

/* Output usage information */
void usage(void) {
    printf( "Zint version %s\n"
            "Encode input data in a barcode and save as a PNG, EPS or SVG file.\n\n"
            "  -h, --help            Display this message.\n"
            "  -t, --types           Display table of barcode types\n"
            "  -i, --input=FILE      Read data from FILE.\n"
            "  -o, --output=FILE     Write image to FILE. (default is out.png)\n"
            "  -d, --data=DATA       Barcode content.\n"
            "  -b, --barcode=NUMBER  Number of barcode type (default is 20 (=Code128)).\n"

            "  --height=NUMBER       Height of symbol in multiples of x-dimension.\n"
            "  -w, --whitesp=NUMBER  Width of whitespace in multiples of x-dimension.\n"



            "  --border=NUMBER       Width of border in multiples of x-dimension.\n"
            "  --box                 Add a box.\n"
            "  --bind                Add boundary bars.\n"
            "  -r, --reverse         Reverse colours (white on black).\n"
            "  --fg=COLOUR           Specify a foreground colour.\n"
            "  --bg=COLOUR           Specify a background colour.\n"

            "  --scale=NUMBER        Adjust size of output image.\n"

            "  --directpng           Send PNG output to stdout\n"
            "  --directeps           Send EPS output to stdout\n"
            "  --directsvg           Send SVG output to stdout\n"

            "  --dump                Dump hexadecimal representation to stdout\n"
            "  --rotate=NUMBER       Rotate symbol (PNG output only).\n"

            "  --cols=NUMBER         (PDF417) Number of columns.\n"

            "  --vers=NUMBER         (QR Code) Version\n"
            "  --secure=NUMBER       (PDF417 and QR Code) Error correction level.\n"
            "  --primary=STRING      (Maxicode and Composite) Structured primary message.\n"
            "  --mode=NUMBER         (Maxicode and Composite) Set encoding mode.\n"
            "  --gs1                 Treat input as GS1 data\n"





            "  --binary              Treat input as Binary data\n"
            "  --notext              Remove human readable text\n"





            "  --square              Force Data Matrix symbols to be square\n"
            "  --dmre                Allow Data Matrix Rectangular Extended\n"
            "  --init                Create reader initialisation symbol (Code 128)\n"
            "  --smalltext           Use half-size text in PNG images\n"
            "  --batch               Treat each line of input as a separate data set\n"


            , ZINT_VERSION);
}


























/* Verifies that a string only uses valid characters */
int validator(char test_string[], char source[]) {
    unsigned int i, j, latch;

    for (i = 0; i < strlen(source); i++) {
        latch = 0;







|
>
|
|
|
|
|
|
|
|
|

|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
>
|
<






|
<
<
<
<
<

>
|
<
>
>
>
|
|
<
<
<
<
>
|
>
|
|
|
>

<
>
|
>
|
<
<
<
|
>
>
>
>
>
|

>
>
>
>
>

|
|
|
|
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76





77
78
79

80
81
82
83
84




85
86
87
88
89
90
91
92

93
94
95
96



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

#ifdef _MSC_VER
#include <malloc.h>
#endif

/* Print list of supported symbologies */
void types(void) {
    printf( " 1: Code 11           50: Logmars                  90: KIX Code\n"
            " 2: Standard 2of5     51: Pharma One-Track         92: Aztec Code\n"
            " 3: Interleaved 2of5  52: PZN                      93: DAFT Code\n"
            " 4: IATA 2of5         53: Pharma Two-Track         97: Micro QR Code\n"
            " 6: Data Logic        55: PDF417                   98: HIBC Code 128\n"
            " 7: Industrial 2of5   56: PDF417 Trunc             99: HIBC Code 39\n"
            " 8: Code 39           57: Maxicode                102: HIBC Data Matrix\n"
            " 9: Extended Code 39  58: QR Code                 104: HIBC QR Code\n"
            "13: EAN               60: Code 128-B              106: HIBC PDF417\n"
            "14: EAN + Check       63: AP Standard Customer    108: HIBC MicroPDF417\n"
            "16: GS1-128           66: AP Reply Paid           110: HIBC Codablock-F\n"
            "18: Codabar           67: AP Routing              112: HIBC Aztec Code\n"
            "20: Code 128          68: AP Redirection          115: DotCode\n"
            "21: Leitcode          69: ISBN                    116: Han Xin Code\n"
            "22: Identcode         70: RM4SCC                  128: Aztec Runes\n"
            "23: Code 16k          71: Data Matrix             129: Code 32\n"
            "24: Code 49           72: EAN-14                  130: Comp EAN\n"
            "25: Code 93           74: Codablock-F             131: Comp GS1-128\n"
            "28: Flattermarken     75: NVE-18                  132: Comp DataBar Omni\n"
            "29: GS1 DataBar Omni  76: Japanese Post           133: Comp DataBar Ltd\n"
            "30: GS1 DataBar Ltd   77: Korea Post              134: Comp DataBar ExpOm\n"
            "31: GS1 DataBar ExpOm 79: GS1 DataBar Stack       135: Comp UPC-A\n"
            "32: Telepen Alpha     80: GS1 DataBar Stack Omni  136: Comp UPC-E\n"
            "34: UPC-A             81: GS1 DataBar ESO         137: Comp DataBar Stack\n"
            "35: UPC-A + Check     82: Planet                  138: Comp DataBar Stack Omni\n"
            "37: UPC-E             84: MicroPDF                139: Comp DataBar ESO\n"
            "38: UPC-E + Check     85: USPS OneCode            140: Channel Code\n"
            "40: Postnet           86: UK Plessey              141: Code One\n"
            "47: MSI Plessey       87: Telepen Numeric         142: Grid Matrix\n"
            "49: FIM               89: ITF-14\n"

            );
}

/* Output usage information */
void usage(void) {
    printf( "Zint version %s\n"
            "Encode input data in a barcode and save as a PNG, BMP, GIF, PCX, EPS or SVG file.\n\n"





            "  -b, --barcode=NUMBER  Number of barcode type (default is 20 (=Code128)).\n"
            "  --batch               Treat each line of input file as a separate data set\n"
            "  --bg=COLOUR           Specify a background colour (in hex)\n"

            "  --binary              Treat input as raw binary data\n"
            "  --bind                Add boundary bars\n"
            "  --bold                Use bold text\n"
            "  --border=NUMBER       Set width of border in multiples of x-dimension\n"
            "  --box                 Add a box around the symbol\n"




            "  --cmyk                Use CMYK colour space in EPS symbols\n"
            "  --cols=NUMBER         Set the number of data columns in symbol\n"
            "  -d, --data=DATA       Set the symbol content\n"
            "  --direct              Send output to stdout\n"
            "  --dotsize=NUMBER      Set radius of dots in dotty mode\n"
            "  --dotty               Use dots instead of squares for matrix symbols\n"
            "  --dmre                Allow Data Matrix Rectangular Extended\n"
            "  --dump                Dump hexadecimal representation to stdout\n"

            "  -e, --ecinos          Display table of ECI character encodings\n"
            "  --eci=NUMBER          Set the ECI mode for raw data\n"
            "  --filetype=TYPE       Set output file type (PNG/EPS/SVG/PNG/EPS/GIF/TXT)\n"
            "  --fg=COLOUR           Specify a foreground colour (in hex)\n"



            "  --gs1                 Treat input as GS1 compatible data\n"
            "  -h, --help            Display help message\n"
            "  --height=NUMBER       Set height of symbol in multiples of x-dimension\n"
            "  -i, --input=FILE      Read input data from FILE\n"
            "  --init                Create reader initialisation/programming symbol\n"
            "  --mirror              Use batch data to determine filename\n"
            "  --mode=NUMBER         Set encoding mode (Maxicode/Composite)\n"
            "  --notext              Remove human readable text\n"
            "  -o, --output=FILE     Send output to FILE. (default is out.png)\n"
            "  --primary=STRING      Set structured primary message (Maxicode/Composite)\n"
            "  --secure=NUMBER       Set error correction level\n"
            "  --scale=NUMBER        Adjust size of x-dimension\n"
            "  --small               Use half-size text in PNG images\n"
            "  --square              Force Data Matrix symbols to be square\n"
            "  -r, --reverse         Reverse colours (white on black)\n"
            "  --rotate=NUMBER       Rotate symbol by NUMBER degrees (PNG/BMP/PCX)\n"
            "  --rows=NUMBER         Set number of rows (Codablock-F)\n"
            "  -t, --types           Display table of barcode types\n"
            "  --vers=NUMBER         Set symbol version (QR Code/Han Xin)\n"
            "  -w, --whitesp=NUMBER  Set Width of whitespace in multiples of x-dimension\n"
            , ZINT_VERSION);
}

/* Display supported ECI codes */
void show_eci(void) {
    printf( " 3: ISO-8859-1 - Latin alphabet No. 1 (default)\n"
            " 4: ISO-8859-2 - Latin alphabet No. 2\n"
            " 5: ISO-8859-3 - Latin alphabet No. 3\n"
            " 6: ISO-8859-4 - Latin alphabet No. 4\n"
            " 7: ISO-8859-5 - Latin/Cyrillic alphabet\n"
            " 8: ISO-8859-6 - Latin/Arabic alphabet\n"
            " 9: ISO-8859-7 - Latin/Greek alphabet\n"
            "10: ISO-8859-8 - Latin/Hebrew alphabet\n"
            "11: ISO-8859-9 - Latin alphabet No. 5\n"
            "12: ISO-8859-10 - Latin alphabet No. 6\n"
            "13: ISO-8859-11 - Latin/Thai alphabet\n"
            "15: ISO-8859-13 - Latin alphabet No. 7\n"
            "16: ISO-8859-14 - Latin alphabet No. 8 (Celtic)\n"
            "17: ISO-8859-15 - Latin alphabet No. 9\n"
            "18: ISO-8859-16 - Latin alphabet No. 10\n"
            "21: Windows-1250\n"
            "22: Windows-1251\n"
            "23: Windows-1252\n"
            "24: Windows-1256\n"
            "26: Unicode (UTF-8)\n"
    );
}

/* Verifies that a string only uses valid characters */
int validator(char test_string[], char source[]) {
    unsigned int i, j, latch;

    for (i = 0; i < strlen(source); i++) {
        latch = 0;
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269


270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324































325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372


373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415

416





417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437


438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    j = strlen(dest);
    n = strlen(source);
    for (i = 0; i <= n; i++) {
        dest[i + j] = source[i];
    }
}

int batch_process(struct zint_symbol *symbol, char *filename) {
    FILE *file;
    unsigned char buffer[7100];
    unsigned char character = 0;
    int posn = 0, error_number = 0, line_count = 1;
    char output_file[127];
    char number[12], reverse_number[12];
    int inpos, local_line_count;
    char format_string[127], reversed_string[127], format_char;
    int format_len, i;
    char adjusted[2];

    memset(buffer, 0, sizeof (unsigned char) * 7100);
    if (symbol->outfile[0] == '\0') {
        strcpy(format_string, "~~~~~.png");

    } else {
        if (strlen(format_string) < 127) {
            strcpy(format_string, symbol->outfile);
        } else {
            strcpy(symbol->errtxt, "Format string too long");
            return ZINT_ERROR_INVALID_DATA;
        }
    }
    memset(adjusted, 0, sizeof (char) * 2);

    if (!strcmp(filename, "-")) {
        file = stdin;
    } else {
        file = fopen(filename, "rb");
        if (!file) {
            strcpy(symbol->errtxt, "Unable to read input file");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    do {
        int intChar;
        intChar = fgetc(file);
        if (intChar == EOF) {
            break;
        }
        character = (unsigned char) intChar;
        if (character == '\n') {
            if (buffer[posn - 1] == '\r') {
                /* CR+LF - assume Windows formatting and remove CR */
                posn--;
                buffer[posn] = '\0';
            }


            inpos = 0;
            local_line_count = line_count;
            memset(number, 0, sizeof (char) * 12);
            memset(reverse_number, 0, sizeof (char) * 12);
            memset(reversed_string, 0, sizeof (char) * 127);
            memset(output_file, 0, sizeof (char) * 127);
            do {
                number[inpos] = itoc(local_line_count % 10);
                local_line_count /= 10;
                inpos++;
            } while (local_line_count > 0);
            number[inpos] = '\0';

            for (i = 0; i < inpos; i++) {
                reverse_number[i] = number[inpos - i - 1];
            }

            format_len = strlen(format_string);
            for (i = format_len; i > 0; i--) {
                format_char = format_string[i - 1];

                switch (format_char) {
                    case '#':
                        if (inpos > 0) {
                            adjusted[0] = reverse_number[inpos - 1];
                            inpos--;
                        } else {
                            adjusted[0] = ' ';
                        }
                        break;
                    case '~':
                        if (inpos > 0) {
                            adjusted[0] = reverse_number[inpos - 1];
                            inpos--;
                        } else {
                            adjusted[0] = '0';
                        }
                        break;
                    case '@':
                        if (inpos > 0) {
                            adjusted[0] = reverse_number[inpos - 1];
                            inpos--;
                        } else {
                            adjusted[0] = '*';
                        }
                        break;
                    default:
                        adjusted[0] = format_string[i - 1];
                        break;
                }
                concat(reversed_string, adjusted);
            }

            for (i = 0; i < format_len; i++) {
                output_file[i] = reversed_string[format_len - i - 1];































            }

            strcpy(symbol->outfile, output_file);
            error_number = ZBarcode_Encode_and_Print(symbol, buffer, posn, 0);
            if (error_number != 0) {
                fprintf(stderr, "On line %d: %s\n", line_count, symbol->errtxt);
                fflush(stderr);
            }
            ZBarcode_Clear(symbol);
            memset(buffer, 0, sizeof (unsigned char) * 7100);
            posn = 0;
            line_count++;
        } else {
            buffer[posn] = character;
            posn++;
        }
        if (posn > 7090) {
            fprintf(stderr, "On line %d: Input data too long\n", line_count);
            fflush(stderr);
            do {
                character = fgetc(file);
            } while ((!feof(file)) && (character != '\n'));
        }
    } while ((!feof(file)) && (line_count < 2000000000));

    if (character != '\n') {
        fprintf(stderr, "Warning: No newline at end of file\n");
        fflush(stderr);
    }

    fclose(file);
    return error_number;
}

int main(int argc, char **argv) {
    struct zint_symbol *my_symbol;
    int c;
    int error_number;
    int rotate_angle;
    int generated;
    int batch_mode;



    error_number = 0;
    rotate_angle = 0;
    generated = 0;
    my_symbol = ZBarcode_Create();
    my_symbol->input_mode = UNICODE_MODE;
    batch_mode = 0;



    if (argc == 1) {
        usage();
        exit(1);
    }

    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {"help", 0, 0, 'h'},
            {"types", 0, 0, 't'},

            {"bind", 0, 0, 0},
            {"box", 0, 0, 0},
            {"directeps", 0, 0, 0},
            {"directpng", 0, 0, 0},
            {"directsvg", 0, 0, 0},
            {"dump", 0, 0, 0},
            {"barcode", 1, 0, 'b'},
            {"height", 1, 0, 0},
            {"whitesp", 1, 0, 'w'},
            {"border", 1, 0, 0},
            {"data", 1, 0, 'd'},
            {"output", 1, 0, 'o'},
            {"input", 1, 0, 'i'},
            {"fg", 1, 0, 0},
            {"bg", 1, 0, 0},
            {"cols", 1, 0, 0},

            {"vers", 1, 0, 0},
            {"rotate", 1, 0, 0},
            {"secure", 1, 0, 0},
            {"reverse", 1, 0, 'r'},
            {"mode", 1, 0, 0},
            {"primary", 1, 0, 0},
            {"scale", 1, 0, 0},
            {"gs1", 0, 0, 0},
            {"kanji", 0, 0, 0},
            {"sjis", 0, 0, 0},
            {"binary", 0, 0, 0},
            {"notext", 0, 0, 0},
            {"square", 0, 0, 0},
            {"dmre", 0, 0, 0},
            {"init", 0, 0, 0},

            {"smalltext", 0, 0, 0},

            {"batch", 0, 0, 0},





            {0, 0, 0, 0}
        };
        c = getopt_long(argc, argv, "htb:w:d:o:i:rcmp", long_options, &option_index);
        if (c == -1) break;

        switch (c) {
            case 0:
                if (!strcmp(long_options[option_index].name, "bind")) {
                    my_symbol->output_options += BARCODE_BIND;
                }
                if (!strcmp(long_options[option_index].name, "box")) {
                    my_symbol->output_options += BARCODE_BOX;
                }
                if (!strcmp(long_options[option_index].name, "init")) {
                    my_symbol->output_options += READER_INIT;
                }
                if (!strcmp(long_options[option_index].name, "smalltext")) {
                    my_symbol->output_options += SMALL_TEXT;
                }
                if (!strcmp(long_options[option_index].name, "directeps")) {
                    my_symbol->output_options += BARCODE_STDOUT;


                    strncpy(my_symbol->outfile, "dummy.eps", 10);
                }
                if (!strcmp(long_options[option_index].name, "directpng")) {
                    my_symbol->output_options += BARCODE_STDOUT;
                    strncpy(my_symbol->outfile, "dummy.png", 10);
                }
                if (!strcmp(long_options[option_index].name, "directsvg")) {
                    my_symbol->output_options += BARCODE_STDOUT;
                    strncpy(my_symbol->outfile, "dummy.svg", 10);
                }
                if (!strcmp(long_options[option_index].name, "dump")) {
                    my_symbol->output_options += BARCODE_STDOUT;
                    strncpy(my_symbol->outfile, "dummy.txt", 10);
                }
                if (!strcmp(long_options[option_index].name, "gs1")) {
                    my_symbol->input_mode = GS1_MODE;







|




|





|


|
>




|










|

















>
>
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















|








|














>
>







>
>











>


|
<
<











>















>
|
>

>
>
>
>
>


|













|


|
|
>
>
|

|
|
<

|

<







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

523
524
525

526
527
528
529
530
531
532
    j = strlen(dest);
    n = strlen(source);
    for (i = 0; i <= n; i++) {
        dest[i + j] = source[i];
    }
}

int batch_process(struct zint_symbol *symbol, char *filename, int mirror_mode, char *filetype) {
    FILE *file;
    unsigned char buffer[7100];
    unsigned char character = 0;
    int posn = 0, error_number = 0, line_count = 1;
    char output_file[256];
    char number[12], reverse_number[12];
    int inpos, local_line_count;
    char format_string[127], reversed_string[127], format_char;
    int format_len, i;
    char adjusted[2];
    
    memset(buffer, 0, sizeof (unsigned char) * 7100);
    if (symbol->outfile[0] == '\0') {
        strcpy(format_string, "~~~~~.");
        strcat(format_string, filetype);
    } else {
        if (strlen(format_string) < 127) {
            strcpy(format_string, symbol->outfile);
        } else {
            strcpy(symbol->errtxt, "Format string too long (A01)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }
    memset(adjusted, 0, sizeof (char) * 2);

    if (!strcmp(filename, "-")) {
        file = stdin;
    } else {
        file = fopen(filename, "rb");
        if (!file) {
            strcpy(symbol->errtxt, "Unable to read input file (A02)");
            return ZINT_ERROR_INVALID_DATA;
        }
    }

    do {
        int intChar;
        intChar = fgetc(file);
        if (intChar == EOF) {
            break;
        }
        character = (unsigned char) intChar;
        if (character == '\n') {
            if (buffer[posn - 1] == '\r') {
                /* CR+LF - assume Windows formatting and remove CR */
                posn--;
                buffer[posn] = '\0';
            }
            
            if (mirror_mode == 0) {
                inpos = 0;
                local_line_count = line_count;
                memset(number, 0, sizeof (char) * 12);
                memset(reverse_number, 0, sizeof (char) * 12);
                memset(reversed_string, 0, sizeof (char) * 127);
                memset(output_file, 0, sizeof (char) * 127);
                do {
                    number[inpos] = itoc(local_line_count % 10);
                    local_line_count /= 10;
                    inpos++;
                } while (local_line_count > 0);
                number[inpos] = '\0';

                for (i = 0; i < inpos; i++) {
                    reverse_number[i] = number[inpos - i - 1];
                }

                format_len = strlen(format_string);
                for (i = format_len; i > 0; i--) {
                    format_char = format_string[i - 1];

                    switch (format_char) {
                        case '#':
                            if (inpos > 0) {
                                adjusted[0] = reverse_number[inpos - 1];
                                inpos--;
                            } else {
                                adjusted[0] = ' ';
                            }
                            break;
                        case '~':
                            if (inpos > 0) {
                                adjusted[0] = reverse_number[inpos - 1];
                                inpos--;
                            } else {
                                adjusted[0] = '0';
                            }
                            break;
                        case '@':
                            if (inpos > 0) {
                                adjusted[0] = reverse_number[inpos - 1];
                                inpos--;
                            } else {
                                adjusted[0] = '*';
                            }
                            break;
                        default:
                            adjusted[0] = format_string[i - 1];
                            break;
                    }
                    concat(reversed_string, adjusted);
                }

                for (i = 0; i < format_len; i++) {
                    output_file[i] = reversed_string[format_len - i - 1];
                }
            } else {
                /* Name the output file from the data being processed */
                for (i = 0; (i < posn && i < 250); i++) {
                    if (buffer[i] < 0x20) {
                        output_file[i] = '_';
                    } else {
                        switch (buffer[i]) {
                            case 0x21: // !
                            case 0x22: // "
                            case 0x2a: // *
                            case 0x2f: // /
                            case 0x3a: // :
                            case 0x3c: // <
                            case 0x3e: // >
                            case 0x3f: // ?
                            case 0x7c: // |
                            case 0x7f: // DEL
                                output_file[i] = '_';
                                break;
                            default:
                                output_file[i] = buffer[i];
                        }
                    }
                }
                
                /* Add file extension */
                output_file[i] = '.';
                output_file[i + 1] = '\0';
                
                strcat(output_file, filetype);
            }

            strcpy(symbol->outfile, output_file);
            error_number = ZBarcode_Encode_and_Print(symbol, buffer, posn, 0);
            if (error_number != 0) {
                fprintf(stderr, "On line %d: %s\n", line_count, symbol->errtxt);
                fflush(stderr);
            }
            ZBarcode_Clear(symbol);
            memset(buffer, 0, sizeof (unsigned char) * 7100);
            posn = 0;
            line_count++;
        } else {
            buffer[posn] = character;
            posn++;
        }
        if (posn > 7090) {
            fprintf(stderr, "On line %d: Input data too long (A03)\n", line_count);
            fflush(stderr);
            do {
                character = fgetc(file);
            } while ((!feof(file)) && (character != '\n'));
        }
    } while ((!feof(file)) && (line_count < 2000000000));

    if (character != '\n') {
        fprintf(stderr, "Warning: No newline at end of file (A04)\n");
        fflush(stderr);
    }

    fclose(file);
    return error_number;
}

int main(int argc, char **argv) {
    struct zint_symbol *my_symbol;
    int c;
    int error_number;
    int rotate_angle;
    int generated;
    int batch_mode;
    int mirror_mode;
    char filetype[4];

    error_number = 0;
    rotate_angle = 0;
    generated = 0;
    my_symbol = ZBarcode_Create();
    my_symbol->input_mode = UNICODE_MODE;
    batch_mode = 0;
    mirror_mode = 0;
    filetype[0] = '\0';

    if (argc == 1) {
        usage();
        exit(1);
    }

    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {"help", 0, 0, 'h'},
            {"types", 0, 0, 't'},
            {"ecinos", 0, 0, 'e'},
            {"bind", 0, 0, 0},
            {"box", 0, 0, 0},
            {"direct", 0, 0, 0},


            {"dump", 0, 0, 0},
            {"barcode", 1, 0, 'b'},
            {"height", 1, 0, 0},
            {"whitesp", 1, 0, 'w'},
            {"border", 1, 0, 0},
            {"data", 1, 0, 'd'},
            {"output", 1, 0, 'o'},
            {"input", 1, 0, 'i'},
            {"fg", 1, 0, 0},
            {"bg", 1, 0, 0},
            {"cols", 1, 0, 0},
            {"rows", 1, 0, 0},
            {"vers", 1, 0, 0},
            {"rotate", 1, 0, 0},
            {"secure", 1, 0, 0},
            {"reverse", 1, 0, 'r'},
            {"mode", 1, 0, 0},
            {"primary", 1, 0, 0},
            {"scale", 1, 0, 0},
            {"gs1", 0, 0, 0},
            {"kanji", 0, 0, 0},
            {"sjis", 0, 0, 0},
            {"binary", 0, 0, 0},
            {"notext", 0, 0, 0},
            {"square", 0, 0, 0},
            {"dmre", 0, 0, 0},
            {"init", 0, 0, 0},
            {"small", 0, 0, 0},
            {"bold", 0, 0, 0},
            {"cmyk", 0, 0, 0},
            {"batch", 0, 0, 0},
            {"mirror", 0, 0, 0},
            {"dotty", 0, 0, 0},
            {"dotsize", 1, 0, 0},
            {"eci", 1, 0, 'e'},
            {"filetype", 1, 0, 0},
            {0, 0, 0, 0}
        };
        c = getopt_long(argc, argv, "htb:w:d:o:i:rcmpe", long_options, &option_index);
        if (c == -1) break;

        switch (c) {
            case 0:
                if (!strcmp(long_options[option_index].name, "bind")) {
                    my_symbol->output_options += BARCODE_BIND;
                }
                if (!strcmp(long_options[option_index].name, "box")) {
                    my_symbol->output_options += BARCODE_BOX;
                }
                if (!strcmp(long_options[option_index].name, "init")) {
                    my_symbol->output_options += READER_INIT;
                }
                if (!strcmp(long_options[option_index].name, "small")) {
                    my_symbol->output_options += SMALL_TEXT;
                }
                if (!strcmp(long_options[option_index].name, "bold")) {
                    my_symbol->output_options += BOLD_TEXT;
                }
                if (!strcmp(long_options[option_index].name, "cmyk")) {
                    my_symbol->output_options += CMYK_COLOUR;
                }
                if (!strcmp(long_options[option_index].name, "dotty")) {
                    my_symbol->output_options += BARCODE_DOTTY_MODE;

                }
                if (!strcmp(long_options[option_index].name, "direct")) {
                    my_symbol->output_options += BARCODE_STDOUT;

                }
                if (!strcmp(long_options[option_index].name, "dump")) {
                    my_symbol->output_options += BARCODE_STDOUT;
                    strncpy(my_symbol->outfile, "dummy.txt", 10);
                }
                if (!strcmp(long_options[option_index].name, "gs1")) {
                    my_symbol->input_mode = GS1_MODE;
478
479
480
481
482
483
484
485
486
487
488









489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521








522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
















578
579
580
581
582
583
584
585
586
587




588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613




614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645



646
647
648
649
650
651
652
653
                    && my_symbol->option_3 != DM_SQUARE) {
                    my_symbol->option_3 = DM_DMRE;
                }
                if (!strcmp(long_options[option_index].name, "scale")) {
                    my_symbol->scale = (float) (atof(optarg));
                    if (my_symbol->scale < 0.01) {
                        /* Zero and negative values are not permitted */
                        fprintf(stderr, "Invalid scale value\n");
                        fflush(stderr);
                        my_symbol->scale = 1.0;
                    }









                }
                if (!strcmp(long_options[option_index].name, "border")) {
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid border width\n");
                        exit(1);
                    }
                    if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
                        my_symbol->border_width = atoi(optarg);
                    } else {
                        fprintf(stderr, "Border width out of range\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "height")) {
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid symbol height\n");
                        exit(1);
                    }
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 1000)) {
                        my_symbol->height = atoi(optarg);
                    } else {
                        fprintf(stderr, "Symbol height out of range\n");
                        fflush(stderr);
                    }
                }

                if (!strcmp(long_options[option_index].name, "cols")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 30)) {
                        my_symbol->option_2 = atoi(optarg);
                    } else {
                        fprintf(stderr, "Number of columns out of range\n");








                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "vers")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 47)) {
                        my_symbol->option_2 = atoi(optarg);
                    } else {
                        fprintf(stderr, "Invalid QR Code version\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "secure")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 8)) {
                        my_symbol->option_1 = atoi(optarg);
                    } else {
                        fprintf(stderr, "ECC level out of range\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "primary")) {
                    if (strlen(optarg) <= 90) {
                        strcpy(my_symbol->primary, optarg);
                    } else {
                        fprintf(stderr, "Primary data string too long");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "mode")) {
                    if ((optarg[0] >= '0') && (optarg[0] <= '6')) {
                        my_symbol->option_1 = optarg[0] - '0';
                    } else {
                        fprintf(stderr, "Invalid mode\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "rotate")) {
                    /* Only certain inputs allowed */
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid rotation parameter\n");
                        exit(1);
                    }
                    switch (atoi(optarg)) {
                        case 90: rotate_angle = 90;
                            break;
                        case 180: rotate_angle = 180;
                            break;
                        case 270: rotate_angle = 270;
                            break;
                        default: rotate_angle = 0;
                            break;
                    }
                }
                if (!strcmp(long_options[option_index].name, "batch")) {
                    /* Switch to batch processing mode */
                    batch_mode = 1;
















                }
                break;

            case 'h':
                usage();
                break;

            case 't':
                types();
                break;





            case 'b':
                error_number = validator(NESET, optarg);
                if (error_number == ZINT_ERROR_INVALID_DATA) {
                    fprintf(stderr, "Invalid barcode type\n");
                    exit(1);
                }
                my_symbol->symbology = atoi(optarg);
                break;

            case 'w':
                error_number = validator(NESET, optarg);
                if (error_number == ZINT_ERROR_INVALID_DATA) {
                    fprintf(stderr, "Invalid whitespace value\n");
                    exit(1);
                }
                if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
                    my_symbol->whitespace_width = atoi(optarg);
                } else {
                    fprintf(stderr, "Whitespace value out of range");
                    fflush(stderr);
                }
                break;

            case 'd': /* we have some data! */
                if (batch_mode == 0) {




                    error_number = escape_char_process(my_symbol, (unsigned char*) optarg, strlen(optarg));
                    if (error_number == 0) {
                        error_number = ZBarcode_Print(my_symbol, rotate_angle);
                    }
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }
                } else {
                    fprintf(stderr, "Cannot define data in batch mode");
                    fflush(stderr);
                }
                break;

            case 'i': /* Take data from file */
                if (batch_mode == 0) {
                    error_number = ZBarcode_Encode_File(my_symbol, optarg);
                    if (error_number == 0) {
                        error_number = ZBarcode_Print(my_symbol, rotate_angle);
                    }
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }
                } else {
                    /* Take each line of text as a separate data set */



                    error_number = batch_process(my_symbol, optarg);
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }







|



>
>
>
>
>
>
>
>
>




|





|






|





|





|


|
>
>
>
>
>
>
>
>




|


|







|







|







|







|
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>




|








|





|






>
>
>
>












|



















>
>
>
|







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
                    && my_symbol->option_3 != DM_SQUARE) {
                    my_symbol->option_3 = DM_DMRE;
                }
                if (!strcmp(long_options[option_index].name, "scale")) {
                    my_symbol->scale = (float) (atof(optarg));
                    if (my_symbol->scale < 0.01) {
                        /* Zero and negative values are not permitted */
                        fprintf(stderr, "Invalid scale value (A05)\n");
                        fflush(stderr);
                        my_symbol->scale = 1.0;
                    }
                }
                if (!strcmp(long_options[option_index].name, "dotsize")) {
                    my_symbol->dot_size = (float) (atof(optarg));
                    if (my_symbol->dot_size < 0.01) {
                        /* Zero and negative values are not permitted */
                        fprintf(stderr, "Invalid dot radius value (A06)\n");
                        fflush(stderr);
                        my_symbol->dot_size = 4.0 / 5.0;
                    }
                }
                if (!strcmp(long_options[option_index].name, "border")) {
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid border width (A07)\n");
                        exit(1);
                    }
                    if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
                        my_symbol->border_width = atoi(optarg);
                    } else {
                        fprintf(stderr, "Border width out of range (A08)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "height")) {
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid symbol height (A09)\n");
                        exit(1);
                    }
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 1000)) {
                        my_symbol->height = atoi(optarg);
                    } else {
                        fprintf(stderr, "Symbol height out of range (A10)\n");
                        fflush(stderr);
                    }
                }

                if (!strcmp(long_options[option_index].name, "cols")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 66)) {
                        my_symbol->option_2 = atoi(optarg);
                    } else {
                        fprintf(stderr, "Number of columns out of range (A11)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "rows")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 44)) {
                        my_symbol->option_1 = atoi(optarg);
                    } else {
                        fprintf(stderr, "Number of rows out of range (A12)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "vers")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 84)) {
                        my_symbol->option_2 = atoi(optarg);
                    } else {
                        fprintf(stderr, "Invalid Version (A13)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "secure")) {
                    if ((atoi(optarg) >= 1) && (atoi(optarg) <= 8)) {
                        my_symbol->option_1 = atoi(optarg);
                    } else {
                        fprintf(stderr, "ECC level out of range (A14)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "primary")) {
                    if (strlen(optarg) <= 90) {
                        strcpy(my_symbol->primary, optarg);
                    } else {
                        fprintf(stderr, "Primary data string too long (A15)");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "mode")) {
                    if ((optarg[0] >= '0') && (optarg[0] <= '6')) {
                        my_symbol->option_1 = optarg[0] - '0';
                    } else {
                        fprintf(stderr, "Invalid mode (A16)\n");
                        fflush(stderr);
                    }
                }
                if (!strcmp(long_options[option_index].name, "rotate")) {
                    /* Only certain inputs allowed */
                    error_number = validator(NESET, optarg);
                    if (error_number == ZINT_ERROR_INVALID_DATA) {
                        fprintf(stderr, "Invalid rotation parameter (A17)\n");
                        exit(1);
                    }
                    switch (atoi(optarg)) {
                        case 90: rotate_angle = 90;
                            break;
                        case 180: rotate_angle = 180;
                            break;
                        case 270: rotate_angle = 270;
                            break;
                        default: rotate_angle = 0;
                            break;
                    }
                }
                if (!strcmp(long_options[option_index].name, "batch")) {
                    /* Switch to batch processing mode */
                    batch_mode = 1;
                }
                if (!strcmp(long_options[option_index].name, "mirror")) {
                    /* Use filenames which reflect content */
                    mirror_mode = 1;
                }
                if (!strcmp(long_options[option_index].name, "filetype")) {
                    /* Select the type of output file */
                    strncpy(filetype, optarg, (size_t) 3);
                }
                if (!strcmp(long_options[option_index].name, "eci")) {
                    if ((atoi(optarg) >= 0) && (atoi(optarg) <= 30)) {
                        my_symbol->eci = atoi(optarg);
                    } else {
                        fprintf(stderr, "Invalid ECI code (A18)\n");
                        fflush(stderr);
                    }
                }
                break;

            case 'h':
                usage();
                break;

            case 't':
                types();
                break;
                
            case 'e':
                show_eci();
                break;

            case 'b':
                error_number = validator(NESET, optarg);
                if (error_number == ZINT_ERROR_INVALID_DATA) {
                    fprintf(stderr, "Invalid barcode type (A19)\n");
                    exit(1);
                }
                my_symbol->symbology = atoi(optarg);
                break;

            case 'w':
                error_number = validator(NESET, optarg);
                if (error_number == ZINT_ERROR_INVALID_DATA) {
                    fprintf(stderr, "Invalid whitespace value (A20)\n");
                    exit(1);
                }
                if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
                    my_symbol->whitespace_width = atoi(optarg);
                } else {
                    fprintf(stderr, "Whitespace value out of range (A21)");
                    fflush(stderr);
                }
                break;

            case 'd': /* we have some data! */
                if (batch_mode == 0) {
                    if (filetype[0] != '\0') {
                        strcat(my_symbol->outfile, ".");
                        strcat(my_symbol->outfile, filetype);
                    }
                    error_number = escape_char_process(my_symbol, (unsigned char*) optarg, strlen(optarg));
                    if (error_number == 0) {
                        error_number = ZBarcode_Print(my_symbol, rotate_angle);
                    }
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }
                } else {
                    fprintf(stderr, "Cannot define data in batch mode (A22)");
                    fflush(stderr);
                }
                break;

            case 'i': /* Take data from file */
                if (batch_mode == 0) {
                    error_number = ZBarcode_Encode_File(my_symbol, optarg);
                    if (error_number == 0) {
                        error_number = ZBarcode_Print(my_symbol, rotate_angle);
                    }
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }
                } else {
                    /* Take each line of text as a separate data set */
                    if (filetype[0] == '\0') {
                        strcpy(filetype, "png");
                    }
                    error_number = batch_process(my_symbol, optarg, mirror_mode, filetype);
                    generated = 1;
                    if (error_number != 0) {
                        fprintf(stderr, "%s\n", my_symbol->errtxt);
                        fflush(stderr);
                        ZBarcode_Delete(my_symbol);
                        return 1;
                    }
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
                strcpy(my_symbol->bgcolour, "000000");
                break;

            case '?':
                break;

            default:
                fprintf(stderr, "?? getopt error 0%o\n", c);
                fflush(stderr);
        }
    }

    if (optind < argc) {
        fprintf(stderr, "Invalid option ");
        while (optind < argc)
            fprintf(stderr, "%s", argv[optind++]);
        fprintf(stderr, "\n");
        fflush(stderr);
    }

    if (generated == 0) {
        fprintf(stderr, "error: No data received, no symbol generated\n");
        fflush(stderr);
    }

    ZBarcode_Delete(my_symbol);

    return error_number;
}







|













|







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
                strcpy(my_symbol->bgcolour, "000000");
                break;

            case '?':
                break;

            default:
                fprintf(stderr, "?? getopt error 0%o (A23)\n", c);
                fflush(stderr);
        }
    }

    if (optind < argc) {
        fprintf(stderr, "Invalid option ");
        while (optind < argc)
            fprintf(stderr, "%s", argv[optind++]);
        fprintf(stderr, "\n");
        fflush(stderr);
    }

    if (generated == 0) {
        fprintf(stderr, "error: No data received, no symbol generated (A24)\n");
        fflush(stderr);
    }

    ZBarcode_Delete(my_symbol);

    return error_number;
}
Changes to jni/zint/frontend/test.sh.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237




238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343











344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412







413
414
415
416
417
418
419
echo testing Code 11
zint -o bar01.png -b 1 --height=50 --border=10 -d 87654321
zint -o bar01.eps -b 1 --height=50 --border=10 -d 87654321
zint -o bar01.svg -b 1 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Standard
zint -o bar02.png -b 2 --height=50 --border=10 -d 87654321
zint -o bar02.eps -b 2 --height=50 --border=10 -d 87654321
zint -o bar02.svg -b 2 --height=50 --border=10 -d 87654321
echo testing Interleaved 2 of 5
zint -o bar03.png -b 3 --height=50 --border=10 -d 87654321
zint -o bar03.eps -b 3 --height=50 --border=10 -d 87654321
zint -o bar03.svg -b 3 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 IATA
zint -o bar04.png -b 4 --height=50 --border=10 -d 87654321
zint -o bar04.eps -b 4 --height=50 --border=10 -d 87654321
zint -o bar04.svg -b 4 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Data Logic
zint -o bar06.png -b 6 --height=50 --border=10 -d 87654321
zint -o bar06.eps -b 6 --height=50 --border=10 -d 87654321
zint -o bar06.svg -b 6 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Industrial
zint -o bar07.png -b 7 --height=50 --border=10 -d 87654321
zint -o bar07.eps -b 7 --height=50 --border=10 -d 87654321
zint -o bar07.svg -b 7 --height=50 --border=10 -d 87654321
echo testing Code 39
zint -o bar08.png -b 8 --height=50 --border=10 -d CODE39
zint -o bar08.eps -b 8 --height=50 --border=10 -d CODE39
zint -o bar08.svg -b 8 --height=50 --border=10 -d CODE39
echo testing Extended Code 39
zint -o bar09.png -b 9 --height=50 --border=10 -d 'Code 39e'
zint -o bar09.eps -b 9 --height=50 --border=10 -d 'Code 39e'
zint -o bar09.svg -b 9 --height=50 --border=10 -d 'Code 39e'
echo testing EAN8
zint -o bar10.png -b 13 --height=50 --border=10 -d 7654321
zint -o bar10.eps -b 13 --height=50 --border=10 -d 7654321
zint -o bar10.svg -b 13 --height=50 --border=10 -d 7654321
echo testing EAN8 - 2 digits add on
zint -o bar11.png -b 13 --height=50 --border=10 -d 7654321+21
zint -o bar11.eps -b 13 --height=50 --border=10 -d 7654321+21
zint -o bar11.svg -b 13 --height=50 --border=10 -d 7654321+21
echo testing EAN8 - 5 digits add-on
zint -o bar12.png -b 13 --height=50 --border=10 -d 7654321+54321
zint -o bar12.eps -b 13 --height=50 --border=10 -d 7654321+54321
zint -o bar12.svg -b 13 --height=50 --border=10 -d 7654321+54321
echo testing EAN13
zint -o bar13.png -b 13 --height=50 --border=10 -d 210987654321
zint -o bar13.eps -b 13 --height=50 --border=10 -d 210987654321
zint -o bar13.svg -b 13 --height=50 --border=10 -d 210987654321
echo testing EAN13 - 2 digits add-on
zint -o bar14.png -b 13 --height=50 --border=10 -d 210987654321+21
zint -o bar14.eps -b 13 --height=50 --border=10 -d 210987654321+21
zint -o bar14.svg -b 13 --height=50 --border=10 -d 210987654321+21
echo testing EAN13 - 5 digits add-on
zint -o bar15.png -b 13 --height=50 --border=10 -d 210987654321+54321
zint -o bar15.eps -b 13 --height=50 --border=10 -d 210987654321+54321
zint -o bar15.svg -b 13 --height=50 --border=10 -d 210987654321+54321
echo testing GS1-128
zint -o bar16.png -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar16.eps -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar16.svg -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
echo testing CodaBar
zint -o bar18.png -b 18 --height=50 --border=10 -d D765432C
zint -o bar18.eps -b 18 --height=50 --border=10 -d D765432C
zint -o bar18.svg -b 18 --height=50 --border=10 -d D765432C
echo testing Code 128
zint -o bar20.png -b 20 --height=50 --border=10 -d 'Code 128'
zint -o bar20.eps -b 20 --height=50 --border=10 -d 'Code 128'
zint -o bar20.svg -b 20 --height=50 --border=10 -d 'Code 128'
echo testing Deutsche Post Leitcode
zint -o bar21.png -b 21 --height=50 --border=10 -d 3210987654321
zint -o bar21.eps -b 21 --height=50 --border=10 -d 3210987654321
zint -o bar21.svg -b 21 --height=50 --border=10 -d 3210987654321
echo testing Deutsche Post Identcode
zint -o bar22.png -b 22 --height=50 --border=10 -d 10987654321
zint -o bar22.eps -b 22 --height=50 --border=10 -d 10987654321
zint -o bar22.svg -b 22 --height=50 --border=10 -d 10987654321
echo testing Code 16k
zint -o bar23.png -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23.eps -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23.svg -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23a.png -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar23a.eps -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar23a.svg -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing Code 49
zint -o bar24.png -b 24 -d "Demonstration Code 49"
zint -o bar24.eps -b 24 -d "Demonstration Code 49"
zint -o bar24.svg -b 24 -d "Demonstration Code 49"
echo testing Code 93
zint -o bar25.png -b 25 --height=50 --border=10 -d 'Code 93'
zint -o bar25.eps -b 25 --height=50 --border=10 -d 'Code 93'
zint -o bar25.svg -b 25 --height=50 --border=10 -d 'Code 93'
echo testing Flattermarken
zint -o bar28.png -b 28 --height=50 --border=10 -d 87654321
zint -o bar28.eps -b 28 --height=50 --border=10 -d 87654321
zint -o bar28.svg -b 28 --height=50 --border=10 -d 87654321
echo testing DataBar-14
zint -o bar29.png -b 29 --height=33 --border=10 -d 2001234567890
zint -o bar29.eps -b 29 --height=33 --border=10 -d 2001234567890
zint -o bar29.svg -b 29 --height=33 --border=10 -d 2001234567890
echo testing DataBar Limited
zint -o bar30.png -b 30 --height=50 --border=10 -w 2 -d 31234567890
zint -o bar30.eps -b 30 --height=50 --border=10 -w 2 -d 31234567890
zint -o bar30.svg -b 30 --height=50 --border=10 -w 2 -d 31234567890
echo testing DataBar Expanded
zint -o bar31.png -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750"
zint -o bar31.eps -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750"
zint -o bar31.svg -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750"
echo testing Telepen Alpha
zint -o bar32.png -b 32 --height=50 --border=10 -d 'Telepen'
zint -o bar32.eps -b 32 --height=50 --border=10 -d 'Telepen'
zint -o bar32.svg -b 32 --height=50 --border=10 -d 'Telepen'
echo testing UPC A
zint -o bar34.png -b 34 --height=50 --border=10 -d 10987654321
zint -o bar34.eps -b 34 --height=50 --border=10 -d 10987654321
zint -o bar34.svg -b 34 --height=50 --border=10 -d 10987654321
echo testing UPC A - 2 digit add-on
zint -o bar35.png -b 34 --height=50 --border=10 -d 10987654321+21
zint -o bar35.eps -b 34 --height=50 --border=10 -d 10987654321+21
zint -o bar35.svg -b 34 --height=50 --border=10 -d 10987654321+21
echo testing UPC A - 5 digit add-on
zint -o bar36.png -b 36 --height=50 --border=10 -d 10987654321+54321
zint -o bar36.eps -b 36 --height=50 --border=10 -d 10987654321+54321
zint -o bar36.svg -b 36 --height=50 --border=10 -d 10987654321+54321
echo testing UPC E
zint -o bar37.png -b 37 --height=50 --border=10 -d 654321
zint -o bar37.eps -b 37 --height=50 --border=10 -d 654321
zint -o bar37.svg -b 37 --height=50 --border=10 -d 654321
echo testing UPC E - 2 digit add-on
zint -o bar38.png -b 37 --height=50 --border=10 -d 654321+21
zint -o bar38.eps -b 37 --height=50 --border=10 -d 654321+21
zint -o bar38.svg -b 37 --height=50 --border=10 -d 654321+21
echo testing UPC E - 5 digit add-on
zint -o bar39.png -b 37 --height=50 --border=10 -d 654321+54321
zint -o bar39.eps -b 37 --height=50 --border=10 -d 654321+54321
zint -o bar39.svg -b 37 --height=50 --border=10 -d 654321+54321
echo testing PostNet-6
zint -o bar41.png -b 40 --border=10 -d 54321
zint -o bar41.eps -b 40 --border=10 -d 54321
zint -o bar41.svg -b 40 --border=10 -d 54321
echo testing PostNet-10
zint -o bar43.png -b 40 --border=10 -d 987654321
zint -o bar43.eps -b 40 --border=10 -d 987654321
zint -o bar43.svg -b 40 --border=10 -d 987654321
echo testing PostNet-12
zint -o bar45.png -b 40 --border=10 -d 10987654321
zint -o bar45.eps -b 40 --border=10 -d 10987654321
zint -o bar45.svg -b 40 --border=10 -d 10987654321
echo testing MSI Code
zint -o bar47.png -b 47 --height=50 --border=10 -d 87654321
zint -o bar47.eps -b 47 --height=50 --border=10 -d 87654321
zint -o bar47.svg -b 47 --height=50 --border=10 -d 87654321
echo testing FIM
zint -o bar49.png -b 49 --height=50 --border=10 -d D
zint -o bar49.eps -b 49 --height=50 --border=10 -d D
zint -o bar49.svg -b 49 --height=50 --border=10 -d D
echo testing LOGMARS
zint -o bar50.png -b 50 --height=50 --border=10 -d LOGMARS
zint -o bar50.eps -b 50 --height=50 --border=10 -d LOGMARS
zint -o bar50.svg -b 50 --height=50 --border=10 -d LOGMARS
echo testing Pharmacode One-Track
zint -o bar51.png -b 51 --height=50 --border=10 -d 123456
zint -o bar51.eps -b 51 --height=50 --border=10 -d 123456
zint -o bar51.svg -b 51 --height=50 --border=10 -d 123456
echo testing Pharmazentralnumber
zint -o bar52.png -b 52 --height=50 --border=10 -d 654321
zint -o bar52.eps -b 52 --height=50 --border=10 -d 654321
zint -o bar52.svg -b 52 --height=50 --border=10 -d 654321
echo testing Pharmacode Two-Track
zint -o bar53.png -b 53 --height=50 --border=10 -d 12345678
zint -o bar53.eps -b 53 --height=50 --border=10 -d 12345678
zint -o bar53.svg -b 53 --height=50 --border=10 -d 12345678
echo testing PDF417
zint -o bar55.png -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar55.eps -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar55.svg -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
echo testing PDF417 Truncated
zint -o bar56.png -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar56.eps -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar56.svg -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
echo testing Maxicode
zint -o bar57.png -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
zint -o bar57.eps -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
zint -o bar57.svg -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
echo testing QR Code
zint -o bar58.png -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58.eps -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58.svg -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58k.png -b 58 --kanji --border=10 -d "画像内の単語を非表示にする"
zint -o bar58k.eps -b 58 --kanji --border=10 -d "画像内の単語を非表示にする"
zint -o bar58k.svg -b 58 --kanji --border=10 -d "画像内の単語を非表示にする"
echo testing Code 128 Subset B
zint -o bar60.png -b 60 --height=50 --border=10 -d 87654321
zint -o bar60.eps -b 60 --height=50 --border=10 -d 87654321
zint -o bar60.svg -b 60 --height=50 --border=10 -d 87654321
echo testing Australian Post Standard Customer
zint -o bar63.png -b 63 --border=10 -d 87654321
zint -o bar63.eps -b 63 --border=10 -d 87654321
zint -o bar63.svg -b 63 --border=10 -d 87654321
echo testing Australian Post Customer 2
zint -o bar64.png -b 63 --border=10 -d 87654321AUSPS
zint -o bar64.eps -b 63 --border=10 -d 87654321AUSPS
zint -o bar64.svg -b 63 --border=10 -d 87654321AUSPS
echo testing Australian Post Customer 3
zint -o bar65.png -b 63 --border=10 -d '87654321 AUSTRALIA'
zint -o bar65.eps -b 63 --border=10 -d '87654321 AUSTRALIA'
zint -o bar65.svg -b 63 --border=10 -d '87654321 AUSTRALIA'
echo testing Australian Post Reply Paid
zint -o bar66.png -b 66 --border=10 -d 87654321
zint -o bar66.eps -b 66 --border=10 -d 87654321
zint -o bar66.svg -b 66 --border=10 -d 87654321
echo testing Australian Post Routing
zint -o bar67.png -b 67 --border=10 -d 87654321
zint -o bar67.eps -b 67 --border=10 -d 87654321
zint -o bar67.svg -b 67 --border=10 -d 87654321
echo testing Australian Post Redirection
zint -o bar68.png -b 68 --border=10 -d 87654321
zint -o bar68.eps -b 68 --border=10 -d 87654321
zint -o bar68.svg -b 68 --border=10 -d 87654321
echo testing ISBN Code
zint -o bar69.png -b 69 --height=50 --border=10 -d 0333638514
zint -o bar69.eps -b 69 --height=50 --border=10 -d 0333638514
zint -o bar69.svg -b 69 --height=50 --border=10 -d 0333638514
echo testing Royal Mail 4 State
zint -o bar70.png -b 70 --border=10 -d ROYALMAIL
zint -o bar70.eps -b 70 --border=10 -d ROYALMAIL
zint -o bar70.svg -b 70 --border=10 -d ROYALMAIL
echo testing Data Matrix
zint -o bar71.png -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71.eps -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71.svg -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71a.png -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar71a.eps -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar71a.svg -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing EAN-14
zint -o bar72.png -b 72 --height=50 --border=10 -d 3210987654321
zint -o bar72.eps -b 72 --height=50 --border=10 -d 3210987654321
zint -o bar72.svg -b 72 --height=50 --border=10 -d 3210987654321




echo testing NVE-18
zint -o bar75.png -b 75 --height=50 --border=10 -d 76543210987654321
zint -o bar75.eps -b 75 --height=50 --border=10 -d 76543210987654321
zint -o bar75.svg -b 75 --height=50 --border=10 -d 76543210987654321
echo testing Japanese Post
zint -o bar76.png -b 76 --border=10 -d "10000131-3-2-503"
zint -o bar76.eps -b 76 --border=10 -d "10000131-3-2-503"
zint -o bar76.svg -b 76 --border=10 -d "10000131-3-2-503"
echo testing Korea Post
zint -o bar77.png -b 77 --height=50 --border=10 -d 123456
zint -o bar77.eps -b 77 --height=50 --border=10 -d 123456
zint -o bar77.svg -b 77 --height=50 --border=10 -d 123456
echo testing DataBar Truncated
zint -o bar78.png -b 29 --height=13 --border=10 -d 1234567890
zint -o bar78.eps -b 29 --height=13 --border=10 -d 1234567890
zint -o bar78.svg -b 29 --height=13 --border=10 -d 1234567890
echo testing DataBar Stacked
zint -o bar79.png -b 79 --border=10 -d 1234567890
zint -o bar79.eps -b 79 --border=10 -d 1234567890
zint -o bar79.svg -b 79 --border=10 -d 1234567890
echo testing DataBar Stacked Omnidirectional
zint -o bar80.png -b 80 --height=69 --border=10 -d 3456789012
zint -o bar80.eps -b 80 --height=69 --border=10 -d 3456789012
zint -o bar80.svg -b 80 --height=69 --border=10 -d 3456789012
echo testing DataBar Expanded Stacked
zint -o bar81.png -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar81.eps -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar81.svg -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
echo testing Planet 12 Digit
zint -o bar82.png -b 82 --border=10 -d 10987654321
zint -o bar82.eps -b 82 --border=10 -d 10987654321
zint -o bar82.svg -b 82 --border=10 -d 10987654321
echo testing Planet 14 Digit
zint -o bar83.png -b 82 --border=10 -d 3210987654321
zint -o bar83.eps -b 82 --border=10 -d 3210987654321
zint -o bar83.svg -b 82 --border=10 -d 3210987654321
echo testing Micro PDF417
zint -o bar84.png -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint"
zint -o bar84.eps -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint"
zint -o bar84.svg -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint"
echo testing USPS OneCode 4-State Customer Barcode
zint -o bar85.png -b 85 --border=10 -d 01234567094987654321
zint -o bar85.eps -b 85 --border=10 -d 01234567094987654321
zint -o bar85.svg -b 85 --border=10 -d 01234567094987654321
echo testing Plessey Code with bidirectional reading support
zint -o bar86.png -b 86 --height=50 --border=10 -d 87654321
zint -o bar86.eps -b 86 --height=50 --border=10 -d 87654321
zint -o bar86.svg -b 86 --height=50 --border=10 -d 87654321
echo testing Telepen Numeric
zint -o bar87.png -b 87 --height=50 --border=10 -d 87654321
zint -o bar87.eps -b 87 --height=50 --border=10 -d 87654321
zint -o bar87.svg -b 87 --height=50 --border=10 -d 87654321
echo testing ITF-14
zint -o bar89.png -b 89 --height=50 --border=10 -d 3210987654321
zint -o bar89.eps -b 89 --height=50 --border=10 -d 3210987654321
zint -o bar89.svg -b 89 --height=50 --border=10 -d 3210987654321
echo testing KIX Code
zint -o bar90.png -b 90 --border=10 -d '1231FZ13Xhs'
zint -o bar90.eps -b 90 --border=10 -d '1231FZ13Xhs'
zint -o bar90.svg -b 90 --border=10 -d '1231FZ13Xhs'
echo testing Aztec Code
zint -o bar92.png -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92.eps -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92.svg -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92a.png -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar92a.eps -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar92a.svg -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing DAFT Code
zint -o bar93.png -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
zint -o bar93.eps -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
zint -o bar93.svg -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
echo testing Micro QR Code
zint -o bar97.png -b 97 --border=10 -d "MicroQR Code"
zint -o bar97.eps -b 97 --border=10 -d "MicroQR Code"
zint -o bar97.svg -b 97 --border=10 -d "MicroQR Code"
zint -o bar97k.png -b 97 --kanji --border=10 -d "小さい"
zint -o bar97k.eps -b 97 --kanji --border=10 -d "小さい"
zint -o bar97k.svg -b 97 --kanji --border=10 -d "小さい"
echo testing HIBC LIC 128
zint -o bar98.png -b 98 --border=10 -d "A99912345/9901510X3"
zint -o bar98.eps -b 98 --border=10 -d "A99912345/9901510X3"
zint -o bar98.svg -b 98 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC 39
zint -o bar99.png -b 99 --border=10 -d "A123BJC5D6E71"
zint -o bar99.eps -b 99 --border=10 -d "A123BJC5D6E71"
zint -o bar99.svg -b 99 --border=10 -d "A123BJC5D6E71"
echo testing HIBC LIC Data Matrix
zint -o bar102.png -b 102 --border=10 -d "A99912345/9901510X3"
zint -o bar102.eps -b 102 --border=10 -d "A99912345/9901510X3"
zint -o bar102.svg -b 102 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC QR-Code
zint -o bar104.png -b 104 --border=10 -d "A99912345/9901510X3"
zint -o bar104.eps -b 104 --border=10 -d "A99912345/9901510X3"
zint -o bar104.svg -b 104 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC PDF417
zint -o bar106.png -b 106 --border=10 -d "A99912345/9901510X3"
zint -o bar106.eps -b 106 --border=10 -d "A99912345/9901510X3"
zint -o bar106.svg -b 106 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC MicroPDF417
zint -o bar108.png -b 108 --border=10 -d "A99912345/9901510X3"
zint -o bar108.eps -b 108 --border=10 -d "A99912345/9901510X3"
zint -o bar108.svg -b 108 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC Aztec Code
zint -o bar112.png -b 112 --border=10 -d "A99912345/9901510X3"
zint -o bar112.eps -b 112 --border=10 -d "A99912345/9901510X3"
zint -o bar112.svg -b 112 --border=10 -d "A99912345/9901510X3"











echo testing Aztec Runes
zint -o bar128.png -b 128 --border=10 -d 125
zint -o bar128.eps -b 128 --border=10 -d 125
zint -o bar128.svg -b 128 --border=10 -d 125
echo testing Code 23
zint -o bar129.png -b 129 --border=10 -d "12345678"
zint -o bar129.eps -b 129 --border=10 -d "12345678"
zint -o bar129.svg -b 129 --border=10 -d "12345678"
echo testing EAN-8 Composite with CC-A
zint -o bar130.png -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678"
zint -o bar130.eps -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678"
zint -o bar130.svg -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678"
echo testing EAN-13 Composite with CC-A
zint -o bar130a.png -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
zint -o bar130a.eps -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
zint -o bar130a.svg -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
echo testing UCC/EAN-128 Composite with CC-A
zint -o bar131.png -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
zint -o bar131.eps -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
zint -o bar131.svg -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
echo testing UCC/EAN-128 Composite with CC-C
zint -o bar131a.png -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
zint -o bar131a.eps -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
zint -o bar131a.svg -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
echo testing DataBar-14 Composite with CC-A
zint -o bar132.png -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102"
zint -o bar132.eps -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102"
zint -o bar132.svg -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102"
echo testing DataBar Limited Composite with CC-B
zint -o bar133.png -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
zint -o bar133.eps -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
zint -o bar133.svg -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
echo testing DataBar Expanded Composite with CC-A
zint -o bar134.png -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
zint -o bar134.eps -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
zint -o bar134.svg -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
echo testing UPC-A Composite with CC-A
zint -o bar135.png -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231"
zint -o bar135.eps -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231"
zint -o bar135.svg -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231"
echo testing UPC-E Composite with CC-A
zint -o bar136.png -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231"
zint -o bar136.eps -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231"
zint -o bar136.svg -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231"
echo testing DataBar-14 Stacked Composite with CC-A
zint -o bar137.png -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar137.eps -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar137.svg -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
echo testing DataBar-14 Stacked Omnidirectional Composite with CC-A
zint -o bar138.png -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar138.eps -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar138.svg -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
echo testing DataBar Expanded Stacked Composite with CC-A
zint -o bar139.png -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
zint -o bar139.eps -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
zint -o bar139.svg -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
echo testing Channel Code
zint -o bar140.png -b 140 --height=100 --border=10 -d "12345"
zint -o bar140.eps -b 140 --height=100 --border=10 -d "12345"
zint -o bar140.svg -b 140 --height=100 --border=10 -d "12345"
echo testing Code One
zint -o bar141.png -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint"
zint -o bar141.eps -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint"
zint -o bar141.svg -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint"
echo testing Grid Matrix
zint -o bar142.png -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint"
zint -o bar142.eps -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint"
zint -o bar142.svg -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint"
echo testing PNG rotation







zint -o barrot0.png -b 130 --height=50 --border=10 --mode=1 --rotate=0 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot90.png -b 130 --height=50 --border=10 --mode=1 --rotate=90 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot180.png -b 130 --height=50 --border=10 --mode=1 --rotate=180 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot270.png -b 130 --height=50 --border=10 --mode=1 --rotate=270 --primary=331234567890+01234 -d "[99]1234-abcd"
echo testing Extended ASCII support
zint -o barext.png --height=50 --border=10 -d "größer"
zint -o barext.svg --height=50 --border=10 -d "größer"

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

|
|


|
|

>
>
>
>

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

|
|


|
|


|
|

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

>
>
>
>
>
>
>
>
>
>
>

|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|

|
>
>
>
>
>
>
>
|
|
|
|

|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
echo testing Code 11
zint -o bar01.txt -b 1 -d 87654321
zint -o bar01.gif -b 1 --height=50 --border=10 -d 87654321
zint -o bar01.svg -b 1 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Standard
zint -o bar02.txt -b 2 -d 87654321
zint -o bar02.gif -b 2 --height=50 --border=10 -d 87654321
zint -o bar02.svg -b 2 --height=50 --border=10 -d 87654321
echo testing Interleaved 2 of 5
zint -o bar03.txt -b 3 -d 87654321
zint -o bar03.gif -b 3 --height=50 --border=10 -d 87654321
zint -o bar03.svg -b 3 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 IATA
zint -o bar04.txt -b 4 -d 87654321
zint -o bar04.gif -b 4 --height=50 --border=10 -d 87654321
zint -o bar04.svg -b 4 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Data Logic
zint -o bar06.txt -b 6 -d 87654321
zint -o bar06.gif -b 6 --height=50 --border=10 -d 87654321
zint -o bar06.svg -b 6 --height=50 --border=10 -d 87654321
echo testing Code 2 of 5 Industrial
zint -o bar07.txt -b 7 -d 87654321
zint -o bar07.gif -b 7 --height=50 --border=10 -d 87654321
zint -o bar07.svg -b 7 --height=50 --border=10 -d 87654321
echo testing Code 39
zint -o bar08.txt -b 8 -d CODE39
zint -o bar08.gif -b 8 --height=50 --border=10 -d CODE39
zint -o bar08.svg -b 8 --height=50 --border=10 -d CODE39
echo testing Extended Code 39
zint -o bar09.txt -b 9 -d 'Code 39e'
zint -o bar09.gif -b 9 --height=50 --border=10 -d 'Code 39e'
zint -o bar09.svg -b 9 --height=50 --border=10 -d 'Code 39e'
echo testing EAN8
zint -o bar10.txt -b 13 -d 7654321
zint -o bar10.gif -b 13 --height=50 --border=10 -d 7654321
zint -o bar10.svg -b 13 --height=50 --border=10 -d 7654321
echo testing EAN8 - 2 digits add on
zint -o bar11.txt -b 13 -d 7654321+21
zint -o bar11.gif -b 13 --height=50 --border=10 -d 7654321+21
zint -o bar11.svg -b 13 --height=50 --border=10 -d 7654321+21
echo testing EAN8 - 5 digits add-on
zint -o bar12.txt -b 13 -d 7654321+54321
zint -o bar12.gif -b 13 --height=50 --border=10 -d 7654321+54321
zint -o bar12.svg -b 13 --height=50 --border=10 -d 7654321+54321
echo testing EAN13
zint -o bar13.txt -b 13 -d 210987654321
zint -o bar13.gif -b 13 --height=50 --border=10 -d 210987654321
zint -o bar13.svg -b 13 --height=50 --border=10 -d 210987654321
echo testing EAN13 - 2 digits add-on
zint -o bar14.txt -b 13 -d 210987654321+21
zint -o bar14.gif -b 13 --height=50 --border=10 -d 210987654321+21
zint -o bar14.svg -b 13 --height=50 --border=10 -d 210987654321+21
echo testing EAN13 - 5 digits add-on
zint -o bar15.txt -b 13 -d 210987654321+54321
zint -o bar15.gif -b 13 --height=50 --border=10 -d 210987654321+54321
zint -o bar15.svg -b 13 --height=50 --border=10 -d 210987654321+54321
echo testing GS1-128
zint -o bar16.txt -b 16 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar16.gif -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar16.svg -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
echo testing CodaBar
zint -o bar18.txt -b 18 -d D765432C
zint -o bar18.gif -b 18 --height=50 --border=10 -d D765432C
zint -o bar18.svg -b 18 --height=50 --border=10 -d D765432C
echo testing Code 128
zint -o bar20.txt -b 20 -d 'Code 128'
zint -o bar20.gif -b 20 --height=50 --border=10 -d 'Code 128'
zint -o bar20.svg -b 20 --height=50 --border=10 -d 'Code 128'
echo testing Deutsche Post Leitcode
zint -o bar21.txt -b 21 -d 3210987654321
zint -o bar21.gif -b 21 --height=50 --border=10 -d 3210987654321
zint -o bar21.svg -b 21 --height=50 --border=10 -d 3210987654321
echo testing Deutsche Post Identcode
zint -o bar22.txt -b 22 -d 10987654321
zint -o bar22.gif -b 22 --height=50 --border=10 -d 10987654321
zint -o bar22.svg -b 22 --height=50 --border=10 -d 10987654321
echo testing Code 16k
zint -o bar23.txt -b 23 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23.gif -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23.svg -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint"
zint -o bar23a.txt -b 23 --gs1 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar23a.gif -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar23a.svg -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing Code 49
zint -o bar24.txt -b 24 -d "Demonstration Code 49"
zint -o bar24.gif -b 24 -d "Demonstration Code 49"
zint -o bar24.svg -b 24 -d "Demonstration Code 49"
echo testing Code 93
zint -o bar25.txt -b 25 -d 'Code 93'
zint -o bar25.gif -b 25 --height=50 --border=10 -d 'Code 93'
zint -o bar25.svg -b 25 --height=50 --border=10 -d 'Code 93'
echo testing Flattermarken
zint -o bar28.txt -b 28 -d 87654321
zint -o bar28.gif -b 28 --height=50 --border=10 -d 87654321
zint -o bar28.svg -b 28 --height=50 --border=10 -d 87654321
echo testing DataBar-14
zint -o bar29.txt -b 29 -d 2001234567890
zint -o bar29.gif -b 29 --height=33 --border=10 -d 2001234567890
zint -o bar29.svg -b 29 --height=33 --border=10 -d 2001234567890
echo testing DataBar Limited
zint -o bar30.txt -b 30 -w 2 -d 31234567890
zint -o bar30.gif -b 30 --height=50 --border=10 -w 2 -d 31234567890
zint -o bar30.svg -b 30 --height=50 --border=10 -w 2 -d 31234567890
echo testing DataBar Expanded
zint -o bar31.txt -b 31 -d "[01]90012345678908[3103]001750"
zint -o bar31.gif -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750"
zint -o bar31.svg -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750"
echo testing Telepen Alpha
zint -o bar32.txt -b 32 -d 'Telepen'
zint -o bar32.gif -b 32 --height=50 --border=10 -d 'Telepen'
zint -o bar32.svg -b 32 --height=50 --border=10 -d 'Telepen'
echo testing UPC A
zint -o bar34.txt -b 34 -d 10987654321
zint -o bar34.gif -b 34 --height=50 --border=10 -d 10987654321
zint -o bar34.svg -b 34 --height=50 --border=10 -d 10987654321
echo testing UPC A - 2 digit add-on
zint -o bar35.txt -b 34 -d 10987654321+21
zint -o bar35.gif -b 34 --height=50 --border=10 -d 10987654321+21
zint -o bar35.svg -b 34 --height=50 --border=10 -d 10987654321+21
echo testing UPC A - 5 digit add-on
zint -o bar36.txt -b 36 -d 10987654321+54321
zint -o bar36.gif -b 36 --height=50 --border=10 -d 10987654321+54321
zint -o bar36.svg -b 36 --height=50 --border=10 -d 10987654321+54321
echo testing UPC E
zint -o bar37.txt -b 37 -d 654321
zint -o bar37.gif -b 37 --height=50 --border=10 -d 654321
zint -o bar37.svg -b 37 --height=50 --border=10 -d 654321
echo testing UPC E - 2 digit add-on
zint -o bar38.txt -b 37 -d 654321+21
zint -o bar38.gif -b 37 --height=50 --border=10 -d 654321+21
zint -o bar38.svg -b 37 --height=50 --border=10 -d 654321+21
echo testing UPC E - 5 digit add-on
zint -o bar39.txt -b 37 -d 654321+54321
zint -o bar39.gif -b 37 --height=50 --border=10 -d 654321+54321
zint -o bar39.svg -b 37 --height=50 --border=10 -d 654321+54321
echo testing PostNet-6
zint -o bar41.txt -b 40 -d 54321
zint -o bar41.gif -b 40 --border=10 -d 54321
zint -o bar41.svg -b 40 --border=10 -d 54321
echo testing PostNet-10
zint -o bar43.txt -b 40 -d 987654321
zint -o bar43.gif -b 40 --border=10 -d 987654321
zint -o bar43.svg -b 40 --border=10 -d 987654321
echo testing PostNet-12
zint -o bar45.txt -b 40 -d 10987654321
zint -o bar45.gif -b 40 --border=10 -d 10987654321
zint -o bar45.svg -b 40 --border=10 -d 10987654321
echo testing MSI Code
zint -o bar47.txt -b 47 -d 87654321
zint -o bar47.gif -b 47 --height=50 --border=10 -d 87654321
zint -o bar47.svg -b 47 --height=50 --border=10 -d 87654321
echo testing FIM
zint -o bar49.txt -b 49 -d D
zint -o bar49.gif -b 49 --height=50 --border=10 -d D
zint -o bar49.svg -b 49 --height=50 --border=10 -d D
echo testing LOGMARS
zint -o bar50.txt -b 50 -d LOGMARS
zint -o bar50.gif -b 50 --height=50 --border=10 -d LOGMARS
zint -o bar50.svg -b 50 --height=50 --border=10 -d LOGMARS
echo testing Pharmacode One-Track
zint -o bar51.txt -b 51 -d 123456
zint -o bar51.gif -b 51 --height=50 --border=10 -d 123456
zint -o bar51.svg -b 51 --height=50 --border=10 -d 123456
echo testing Pharmazentralnumber
zint -o bar52.txt -b 52 -d 654321
zint -o bar52.gif -b 52 --height=50 --border=10 -d 654321
zint -o bar52.svg -b 52 --height=50 --border=10 -d 654321
echo testing Pharmacode Two-Track
zint -o bar53.txt -b 53 --border=10 -d 12345678
zint -o bar53.gif -b 53 --height=50 --border=10 -d 12345678
zint -o bar53.svg -b 53 --height=50 --border=10 -d 12345678
echo testing PDF417
zint -o bar55.txt -b 55 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar55.gif -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar55.svg -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
echo testing PDF417 Truncated
zint -o bar56.txt -b 56 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar56.gif -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
zint -o bar56.svg -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint"
echo testing Maxicode
zint -o bar57.txt -b 57 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
zint -o bar57.gif -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
zint -o bar57.svg -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint"
echo testing QR Code
zint -o bar58.txt -b 58 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58.gif -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58.svg -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint"
zint -o bar58k.txt -b 58 --kanji -d "画像内の単語を非表示にする"
zint -o bar58k.gif -b 58 --kanji --border=10 -d "画像内の単語を非表示にする"
zint -o bar58k.svg -b 58 --kanji --border=10 -d "画像内の単語を非表示にする"
echo testing Code 128 Subset B
zint -o bar60.txt -b 60 -d 87654321
zint -o bar60.gif -b 60 --height=50 --border=10 -d 87654321
zint -o bar60.svg -b 60 --height=50 --border=10 -d 87654321
echo testing Australian Post Standard Customer
zint -o bar63.txt -b 63 -d 87654321
zint -o bar63.gif -b 63 --border=10 -d 87654321
zint -o bar63.svg -b 63 --border=10 -d 87654321
echo testing Australian Post Customer 2
zint -o bar64.txt -b 63 -d 87654321AUSPS
zint -o bar64.gif -b 63 --border=10 -d 87654321AUSPS
zint -o bar64.svg -b 63 --border=10 -d 87654321AUSPS
echo testing Australian Post Customer 3
zint -o bar65.txt -b 63 -d '87654321 AUSTRALIA'
zint -o bar65.gif -b 63 --border=10 -d '87654321 AUSTRALIA'
zint -o bar65.svg -b 63 --border=10 -d '87654321 AUSTRALIA'
echo testing Australian Post Reply Paid
zint -o bar66.txt -b 66 -d 87654321
zint -o bar66.gif -b 66 --border=10 -d 87654321
zint -o bar66.svg -b 66 --border=10 -d 87654321
echo testing Australian Post Routing
zint -o bar67.txt -b 67 -d 87654321
zint -o bar67.gif -b 67 --border=10 -d 87654321
zint -o bar67.svg -b 67 --border=10 -d 87654321
echo testing Australian Post Redirection
zint -o bar68.txt -b 68 -d 87654321
zint -o bar68.gif -b 68 --border=10 -d 87654321
zint -o bar68.svg -b 68 --border=10 -d 87654321
echo testing ISBN Code
zint -o bar69.txt -b 69 -d 0333638514
zint -o bar69.gif -b 69 --height=50 --border=10 -d 0333638514
zint -o bar69.svg -b 69 --height=50 --border=10 -d 0333638514
echo testing Royal Mail 4 State
zint -o bar70.txt -b 70 -d ROYALMAIL
zint -o bar70.gif -b 70 --border=10 -d ROYALMAIL
zint -o bar70.svg -b 70 --border=10 -d ROYALMAIL
echo testing Data Matrix
zint -o bar71.txt -b 71 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71.gif -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71.svg -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint"
zint -o bar71a.txt -b 71 --gs1 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar71a.gif -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar71a.svg -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing EAN-14
zint -o bar72.txt -b 72 -d 3210987654321
zint -o bar72.gif -b 72 --height=50 --border=10 -d 3210987654321
zint -o bar72.svg -b 72 --height=50 --border=10 -d 3210987654321
echo testing Codablock-F
zint -o bar74.txt -b 74 -d "Demonstration Codablock-F symbol generated by libzint"
zint -o bar74.gif -b 74 -d "Demonstration Codablock-F symbol generated by libzint"
zint -o bar74.svg -b 74 -d "Demonstration Codablock-F symbol generated by libzint"
echo testing NVE-18
zint -o bar75.txt -b 75 -d 76543210987654321
zint -o bar75.gif -b 75 --height=50 --border=10 -d 76543210987654321
zint -o bar75.svg -b 75 --height=50 --border=10 -d 76543210987654321
echo testing Japanese Post
zint -o bar76.txt -b 76 -d "10000131-3-2-503"
zint -o bar76.gif -b 76 --border=10 -d "10000131-3-2-503"
zint -o bar76.svg -b 76 --border=10 -d "10000131-3-2-503"
echo testing Korea Post
zint -o bar77.txt -b 77 -d 123456
zint -o bar77.gif -b 77 --height=50 --border=10 -d 123456
zint -o bar77.svg -b 77 --height=50 --border=10 -d 123456
echo testing DataBar Truncated
zint -o bar78.txt -b 29 -d 1234567890
zint -o bar78.gif -b 29 --height=13 --border=10 -d 1234567890
zint -o bar78.svg -b 29 --height=13 --border=10 -d 1234567890
echo testing DataBar Stacked
zint -o bar79.txt -b 79 -d 1234567890
zint -o bar79.gif -b 79 --border=10 -d 1234567890
zint -o bar79.svg -b 79 --border=10 -d 1234567890
echo testing DataBar Stacked Omnidirectional
zint -o bar80.txt -b 80 -d 3456789012
zint -o bar80.gif -b 80 --height=69 --border=10 -d 3456789012
zint -o bar80.svg -b 80 --height=69 --border=10 -d 3456789012
echo testing DataBar Expanded Stacked
zint -o bar81.txt -b 81 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar81.gif -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar81.svg -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
echo testing Planet 12 Digit
zint -o bar82.txt -b 82 -d 10987654321
zint -o bar82.gif -b 82 --border=10 -d 10987654321
zint -o bar82.svg -b 82 --border=10 -d 10987654321
echo testing Planet 14 Digit
zint -o bar83.txt -b 82 -d 3210987654321
zint -o bar83.gif -b 82 --border=10 -d 3210987654321
zint -o bar83.svg -b 82 --border=10 -d 3210987654321
echo testing Micro PDF417
zint -o bar84.txt -b 84 -d "Demonstration MicroPDF417 symbol generated by libzint"
zint -o bar84.gif -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint"
zint -o bar84.svg -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint"
echo testing USPS OneCode 4-State Customer Barcode
zint -o bar85.txt -b 85 -d 01234567094987654321
zint -o bar85.gif -b 85 --border=10 -d 01234567094987654321
zint -o bar85.svg -b 85 --border=10 -d 01234567094987654321
echo testing Plessey Code with bidirectional reading support
zint -o bar86.txt -b 86 -d 87654321
zint -o bar86.gif -b 86 --height=50 --border=10 -d 87654321
zint -o bar86.svg -b 86 --height=50 --border=10 -d 87654321
echo testing Telepen Numeric
zint -o bar87.txt -b 87 -d 87654321
zint -o bar87.gif -b 87 --height=50 --border=10 -d 87654321
zint -o bar87.svg -b 87 --height=50 --border=10 -d 87654321
echo testing ITF-14
zint -o bar89.txt -b 89 -d 3210987654321
zint -o bar89.gif -b 89 --height=50 --border=10 -d 3210987654321
zint -o bar89.svg -b 89 --height=50 --border=10 -d 3210987654321
echo testing KIX Code
zint -o bar90.txt -b 90 -d '1231FZ13Xhs'
zint -o bar90.gif -b 90 --border=10 -d '1231FZ13Xhs'
zint -o bar90.svg -b 90 --border=10 -d '1231FZ13Xhs'
echo testing Aztec Code
zint -o bar92.txt -b 92 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92.gif -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92.svg -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint"
zint -o bar92a.txt -b 92 --gs1 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar92a.gif -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
zint -o bar92a.svg -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231"
echo testing DAFT Code
zint -o bar93.txt -b 93 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
zint -o bar93.gif -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
zint -o bar93.svg -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft"
echo testing Micro QR Code
zint -o bar97.txt -b 97 -d "MicroQR Code"
zint -o bar97.gif -b 97 --border=10 -d "MicroQR Code"
zint -o bar97.svg -b 97 --border=10 -d "MicroQR Code"
zint -o bar97k.txt -b 97 --kanji -d "小さい"
zint -o bar97k.gif -b 97 --kanji --border=10 -d "小さい"
zint -o bar97k.svg -b 97 --kanji --border=10 -d "小さい"
echo testing HIBC LIC 128
zint -o bar98.txt -b 98 -d "A99912345/9901510X3"
zint -o bar98.gif -b 98 --border=10 -d "A99912345/9901510X3"
zint -o bar98.svg -b 98 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC 39
zint -o bar99.txt -b 99 -d "A123BJC5D6E71"
zint -o bar99.gif -b 99 --border=10 -d "A123BJC5D6E71"
zint -o bar99.svg -b 99 --border=10 -d "A123BJC5D6E71"
echo testing HIBC LIC Data Matrix
zint -o bar102.txt -b 102 -d "A99912345/9901510X3"
zint -o bar102.gif -b 102 --border=10 -d "A99912345/9901510X3"
zint -o bar102.svg -b 102 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC QR-Code
zint -o bar104.txt -b 104 -d "A99912345/9901510X3"
zint -o bar104.gif -b 104 --border=10 -d "A99912345/9901510X3"
zint -o bar104.svg -b 104 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC PDF417
zint -o bar106.txt -b 106 -d "A99912345/9901510X3"
zint -o bar106.gif -b 106 --border=10 -d "A99912345/9901510X3"
zint -o bar106.svg -b 106 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC MicroPDF417
zint -o bar108.txt -b 108 -d "A99912345/9901510X3"
zint -o bar108.gif -b 108 --border=10 -d "A99912345/9901510X3"
zint -o bar108.svg -b 108 --border=10 -d "A99912345/9901510X3"
echo testing HIBC LIC Aztec Code
zint -o bar112.txt -b 112 -d "A99912345/9901510X3"
zint -o bar112.gif -b 112 --border=10 -d "A99912345/9901510X3"
zint -o bar112.svg -b 112 --border=10 -d "A99912345/9901510X3"
echo testing DotCode
zint -o bar115.txt -b 115 -d "Demonstration DotCode symbol generated by libzint"
zint -o bar115.gif -b 115 --scale=5 --border=10 -d "Demonstration DotCode symbol generated by libzint"
zint -o bar115.svg -b 115 --scale=5 --border=10 -d "Demonstration DotCode symbol generated by libzint"
zint -o bar115a.txt -b 115 --gs1 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar115a.gif -b 115 --gs1 --scale=5 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
zint -o bar115a.svg -b 115 --gs1 --scale=5 --border=10 -d "[01]98898765432106[3202]012345[15]991231"
echo testing Han Xin Code
zint -o bar116.txt -b 116 -d "Demonstration Han Xin symbol generated by libzint"
zint -o bar116.gif -b 116 --scale=5 --border=10 -d "Demonstration Han Xin symbol generated by libzint"
zint -o bar116.svg -b 116 --scale=5 --border=10 -d "Demonstration Han Xin symbol generated by libzint"
echo testing Aztec Runes
zint -o bar128.txt -b 128 -d 125
zint -o bar128.gif -b 128 --border=10 -d 125
zint -o bar128.svg -b 128 --border=10 -d 125
echo testing Code 23
zint -o bar129.txt -b 129 -d "12345678"
zint -o bar129.gif -b 129 --border=10 -d "12345678"
zint -o bar129.svg -b 129 --border=10 -d "12345678"
echo testing EAN-8 Composite with CC-A
zint -o bar130.txt -b 130 --mode=1 --primary=1234567 -d "[21]A12345678"
zint -o bar130.gif -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678"
zint -o bar130.svg -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678"
echo testing EAN-13 Composite with CC-A
zint -o bar130a.txt -b 130 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
zint -o bar130a.gif -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
zint -o bar130a.svg -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd"
echo testing UCC/EAN-128 Composite with CC-A
zint -o bar131.txt -b 131 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
zint -o bar131.gif -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
zint -o bar131.svg -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG"
echo testing UCC/EAN-128 Composite with CC-C
zint -o bar131a.txt -b 131 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
zint -o bar131a.gif -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
zint -o bar131a.svg -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG"
echo testing DataBar-14 Composite with CC-A
zint -o bar132.txt -b 132 --mode=1 --primary=361234567890 -d "[11]990102"
zint -o bar132.gif -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102"
zint -o bar132.svg -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102"
echo testing DataBar Limited Composite with CC-B
zint -o bar133.txt -b 133 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
zint -o bar133.gif -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
zint -o bar133.svg -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv"
echo testing DataBar Expanded Composite with CC-A
zint -o bar134.txt -b 134 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
zint -o bar134.gif -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
zint -o bar134.svg -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E"
echo testing UPC-A Composite with CC-A
zint -o bar135.txt -b 135 --mode=1 --primary=10987654321 -d "[15]021231"
zint -o bar135.gif -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231"
zint -o bar135.svg -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231"
echo testing UPC-E Composite with CC-A
zint -o bar136.txt -b 136 --mode=1 --primary=121230 -d "[15]021231"
zint -o bar136.gif -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231"
zint -o bar136.svg -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231"
echo testing DataBar-14 Stacked Composite with CC-A
zint -o bar137.txt -b 137 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar137.gif -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar137.svg -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
echo testing DataBar-14 Stacked Omnidirectional Composite with CC-A
zint -o bar138.txt -b 138 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar138.gif -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
zint -o bar138.svg -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200"
echo testing DataBar Expanded Stacked Composite with CC-A
zint -o bar139.txt -b 139 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
zint -o bar139.gif -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
zint -o bar139.svg -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678"
echo testing Channel Code
zint -o bar140.txt -b 140 -d "12345"
zint -o bar140.gif -b 140 --height=100 --border=10 -d "12345"
zint -o bar140.svg -b 140 --height=100 --border=10 -d "12345"
echo testing Code One
zint -o bar141.txt -b 141 -d "Demonstration Code One symbol generated by libzint"
zint -o bar141.gif -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint"
zint -o bar141.svg -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint"
echo testing Grid Matrix
zint -o bar142.txt -b 142 -d "Demonstration Grid Matrix generated by libzint"
zint -o bar142.gif -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint"
zint -o bar142.svg -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint"
echo testing output formats
zint -o barout.png -b 58 --border=10 -d "Sample output QR Code"
zint -o barout.gif -b 58 --border=10 -d "Sample output QR Code"
zint -o barout.bmp -b 58 --border=10 -d "Sample output QR Code"
zint -o barout.pcx -b 58 --border=10 -d "Sample output QR Code"
zint -o barout.eps -b 58 --border=10 -d "Sample output QR Code"
zint -o barout.svg -b 58 --border=10 -d "Sample output QR Code"
echo testing image rotation
zint -o barrot0.gif -b 130 --height=50 --border=10 --mode=1 --rotate=0 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot90.gif -b 130 --height=50 --border=10 --mode=1 --rotate=90 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot180.gif -b 130 --height=50 --border=10 --mode=1 --rotate=180 --primary=331234567890+01234 -d "[99]1234-abcd"
zint -o barrot270.gif -b 130 --height=50 --border=10 --mode=1 --rotate=270 --primary=331234567890+01234 -d "[99]1234-abcd"
echo testing Extended ASCII support
zint -o barext.txt -d "größer"
zint -o barext.svg --height=50 --border=10 -d "größer"
Changes to jni/zint/frontend_qt4/exportwindow.cpp.
70
71
72
73
74
75
76
77



78
79
80
81



82
83
84
85
86
87
88
	
	lines = output_data.count(QChar('\n'), Qt::CaseInsensitive);
	inputpos = 0;
	
	switch(cmbFileFormat->currentIndex()) {
#ifdef NO_PNG
		case 0: suffix = ".eps"; break;
		case 1: suffix = ".svg"; break;



#else
                case 0: suffix = ".png"; break;
		case 1: suffix = ".eps"; break;
		case 2: suffix = ".svg"; break;



#endif
	}
	
	for(i = 0; i < lines; i++) {
		datalen = 0;
		for(j = inputpos; ((output_data[j] != '\n') && (j < output_data.length())); j++) {
			datalen++;







|
>
>
>



|
>
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
	
	lines = output_data.count(QChar('\n'), Qt::CaseInsensitive);
	inputpos = 0;
	
	switch(cmbFileFormat->currentIndex()) {
#ifdef NO_PNG
		case 0: suffix = ".eps"; break;
		case 1: suffix = ".gif"; break;
                case 2: suffix = ".svg"; break;
                case 3: suffix = ".bmp"; break;
                case 4: suffix = ".pcx"; break;
#else
                case 0: suffix = ".png"; break;
		case 1: suffix = ".eps"; break;
		case 2: suffix = ".gif"; break;
                case 3: suffix = ".svg"; break;
                case 4: suffix = ".bmp"; break;
                case 5: suffix = ".pcx"; break;
#endif
	}
	
	for(i = 0; i < lines; i++) {
		datalen = 0;
		for(j = inputpos; ((output_data[j] != '\n') && (j < output_data.length())); j++) {
			datalen++;
Changes to jni/zint/frontend_qt4/extExport.ui.
71
72
73
74
75
76
77





78
79
80
81
82










83
84
85
86
87
88
89
    </property>
   </item>
   <item>
    <property name="text">
     <string>Encapsulated Post Script (*.eps)</string>
    </property>
   </item>





   <item>
    <property name="text">
     <string>Scalable Vector Graphic (*.svg)</string>
    </property>
   </item>










  </widget>
  <widget class="QToolButton" name="btnDestPath">
   <property name="geometry">
    <rect>
     <x>410</x>
     <y>10</y>
     <width>30</width>







>
>
>
>
>





>
>
>
>
>
>
>
>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    </property>
   </item>
   <item>
    <property name="text">
     <string>Encapsulated Post Script (*.eps)</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>Graphics Interchange Format (*.gif)</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>Scalable Vector Graphic (*.svg)</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>Windows Bitmap (*.bmp)</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>ZSoft PC Painter Image (*.pcx)</string>
    </property>
   </item>
  </widget>
  <widget class="QToolButton" name="btnDestPath">
   <property name="geometry">
    <rect>
     <x>410</x>
     <y>10</y>
     <width>30</width>
Changes to jni/zint/frontend_qt4/frontend_qt4.pro.
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36

37

38
39
40
41
42
43
44
         grpAztec.ui \
         grpC128.ui \
         grpC16k.ui \
         grpC39.ui \
         grpC49.ui \
         grpChannel.ui \
         grpCodeOne.ui \

         grpDBExtend.ui \
         grpDM.ui \
         grpGrid.ui \
         grpMaxicode.ui \
         grpMicroPDF.ui \
         grpMQR.ui \
         grpMSICheck.ui \
         grpPDF417.ui \
         grpQR.ui \

         mainWindow.ui


SOURCES += barcodeitem.cpp \
        datawindow.cpp \
        exportwindow.cpp \
        main.cpp \
        mainwindow.cpp \
        sequencewindow.cpp







>









>
|
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
         grpAztec.ui \
         grpC128.ui \
         grpC16k.ui \
         grpC39.ui \
         grpC49.ui \
         grpChannel.ui \
         grpCodeOne.ui \
         grpCodablockF.ui \
         grpDBExtend.ui \
         grpDM.ui \
         grpGrid.ui \
         grpMaxicode.ui \
         grpMicroPDF.ui \
         grpMQR.ui \
         grpMSICheck.ui \
         grpPDF417.ui \
         grpQR.ui \
         grpHX.ui \
         mainWindow.ui \
    grpDotCode.ui

SOURCES += barcodeitem.cpp \
        datawindow.cpp \
        exportwindow.cpp \
        main.cpp \
        mainwindow.cpp \
        sequencewindow.cpp
Added jni/zint/frontend_qt4/grpCodablockF.ui.




















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>grpCodablockF</class>
 <widget class="QWidget" name="grpCodablockF">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>763</width>
    <height>376</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QGridLayout" name="gridLayout">
     <item row="2" column="0">
      <widget class="QRadioButton" name="radCbfSetHeight">
       <property name="text">
        <string>Set Symbol Height (Rows)</string>
       </property>
      </widget>
     </item>
     <item row="1" column="0">
      <widget class="QRadioButton" name="radCbfSetWidth">
       <property name="text">
        <string>Set Symbol Width (Columns)</string>
       </property>
       <property name="checked">
        <bool>false</bool>
       </property>
      </widget>
     </item>
     <item row="1" column="2">
      <widget class="QComboBox" name="cmbCbfWidth">
       <item>
        <property name="text">
         <string>6</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>7</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>8</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>9</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>10</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>11</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>12</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>13</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>14</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>15</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>16</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>17</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>18</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>19</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>20</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>21</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>22</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>23</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>24</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>25</string>
        </property>
       </item>
      </widget>
     </item>
     <item row="2" column="2">
      <widget class="QComboBox" name="cmbCbfHeight">
       <item>
        <property name="text">
         <string>1</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>2</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>3</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>4</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>5</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>6</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>7</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>8</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>9</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>10</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>11</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>12</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>13</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>14</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>15</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>16</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>17</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>18</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>19</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>20</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>21</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>22</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>23</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>24</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>25</string>
        </property>
       </item>
      </widget>
     </item>
     <item row="0" column="0">
      <widget class="QRadioButton" name="radCbfAutosize">
       <property name="text">
        <string>Automatic Size</string>
       </property>
       <property name="checked">
        <bool>true</bool>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
Added jni/zint/frontend_qt4/grpDotCode.ui.


































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>grpDotCode</class>
 <widget class="QWidget" name="grpDotCode">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>390</width>
    <height>223</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QGridLayout" name="gridLayout">
     <item row="0" column="1">
      <widget class="QComboBox" name="cmbDotCols">
       <property name="maxVisibleItems">
        <number>11</number>
       </property>
       <item>
        <property name="text">
         <string>Automatic</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>1</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>2</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>3</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>4</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>5</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>6</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>7</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>8</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>9</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>10</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>11</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>12</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>13</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>14</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>15</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>16</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>17</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>18</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>19</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>20</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>21</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>22</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>23</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>24</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>25</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>26</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>27</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>28</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>29</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>30</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>31</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>32</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>33</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>34</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>35</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>36</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>37</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>38</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>39</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>40</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>41</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>42</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>43</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>44</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>45</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>46</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>47</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>48</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>49</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>50</string>
        </property>
       </item>
      </widget>
     </item>
     <item row="1" column="0">
      <widget class="QLabel" name="lblDotSize">
       <property name="enabled">
        <bool>true</bool>
       </property>
       <property name="text">
        <string>Dot Size:</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
       </property>
      </widget>
     </item>
     <item row="0" column="0">
      <widget class="QLabel" name="lblDotCols">
       <property name="text">
        <string>&amp;Number of Data Columns:</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
       </property>
       <property name="buddy">
        <cstring>cmbDotCols</cstring>
       </property>
      </widget>
     </item>
     <item row="1" column="1">
      <widget class="QLineEdit" name="txtDotSize">
       <property name="enabled">
        <bool>true</bool>
       </property>
       <property name="text">
        <string>0.8</string>
       </property>
      </widget>
     </item>
     <item row="2" column="0">
      <widget class="QRadioButton" name="radDotStan">
       <property name="text">
        <string>Standard &amp;Mode</string>
       </property>
       <property name="checked">
        <bool>true</bool>
       </property>
      </widget>
     </item>
     <item row="2" column="1">
      <widget class="QRadioButton" name="radDotGs1">
       <property name="text">
        <string>GS-&amp;1 Data Mode</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>52</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
Added jni/zint/frontend_qt4/grpHX.ui.


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>grpHX</class>
 <widget class="QWidget" name="grpHX">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>441</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>421</width>
     <height>100</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QRadioButton" name="radHXAuto">
      <property name="text">
       <string>A&amp;utomatic Resizing</string>
      </property>
      <property name="checked">
       <bool>true</bool>
      </property>
     </widget>
    </item>
    <item row="1" column="0">
     <widget class="QRadioButton" name="radHXSize">
      <property name="text">
       <string>Adjust Si&amp;ze To:</string>
      </property>
     </widget>
    </item>
    <item row="1" column="1">
     <widget class="QComboBox" name="cmbHXSize">
      <property name="enabled">
       <bool>true</bool>
      </property>
      <item>
       <property name="text">
        <string>23 x 23 (Version 1)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>25 x 25 (Version 2)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>27 x 27 (Version 3)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>29 x 29 (Version 4)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>31 x 31 (Version 5)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>33 x 33 (Version 6)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>35 x 35 (Version 7)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>37 x 37 (Version 8)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>39 x 39 (Version 9)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>41 x 41 (Version 10)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>43 x 43 (Version 11)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>45 x 45 (Version 12)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>47 x 47 (Version 13)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>49 x 49 (Version 14)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>51 x 51 (Version 15)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>53 x 53 (Version 16)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>55 x 55 (Version 17)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>57 x 57 (Version 18)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>59 x 59 (Version 19)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>61 x 61 (Version 20)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>63 x 63 (Version 21)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>65 x 65 (Version 22)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>67 x 67 (Version 23)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>69 x 69 (Version 24)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>71 x 71 (Version 25)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>73 x 73 (Version 26)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>75 x 75 (Version 27)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>77 x 77 (Version 28)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>79 x 79 (Version 29)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>81 x 81 (Version 30)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>83 x 83 (Version 31)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>85 x 85 (Version 32)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>87 x 87 (Version 33)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>89 x 89 (Version 34)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>91 x 91 (Version 35)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>93 x 93 (Version 36)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>95 x 95 (Version 37)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>97 x 97 (Version 38)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>99 x 99 (Version 39)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>101 x 101 (Version 40)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>103 x 103 (Version 41)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>105 x 105 (Version 42)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>107 x 107 (Version 43)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>109 x 109 (Version 44)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>111 x 111 (Version 45)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>113 x 113 (Version 46)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>115 x 115 (Version 47)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>117 x 117 (Version 48)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>119 x 119 (Version 49)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>121 x 121 (Version 50)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>123 x 123 (Version 51)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>125 x 125 (Version 52)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>127 x 127 (Version 53)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>129 x 129 (Version 54)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>131 x 131 (Version 55)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>133 x 133 (Version 56)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>135 x 135 (Version 57)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>137 x 137 (Version 58)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>139 x 139 (Version 59)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>141 x 141 (Version 60)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>143 x 143 (Version 61)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>145 x 145 (Version 62)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>147 x 147 (Version 63)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>149 x 149 (Version 64)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>151 x 151 (Version 65)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>153 x 153 (Version 66)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>155 x 155 (Version 67)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>157 x 157 (Version 68)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>159 x 159 (Version 69)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>161 x 161 (Version 70)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>163 x 163 (Version 71)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>165 x 165 (Version 72)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>167 x 167 (Version 73)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>169 x 169 (Version 74)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>171 x 171 (Version 75)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>173 x 173 (Version 76)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>175 x 175 (Version 77)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>177 x 177 (Version 78)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>179 x 179 (Version 79)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>181 x 181 (Version 80)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>183 x 183 (Version 81)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>185 x 185 (Version 82)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>187 x 187 (Version 83)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>189 x 189 (Version 84)</string>
       </property>
      </item>
     </widget>
    </item>
    <item row="2" column="0">
     <widget class="QRadioButton" name="radHXECC">
      <property name="text">
       <string>Add &amp;Error Correction:</string>
      </property>
     </widget>
    </item>
    <item row="2" column="1">
     <widget class="QComboBox" name="cmbHXECC">
      <property name="enabled">
       <bool>true</bool>
      </property>
      <item>
       <property name="text">
        <string>~8% (Level L1)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>~15% (Level L2)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>~23% (Level L3)</string>
       </property>
      </item>
      <item>
       <property name="text">
        <string>~30% (Level L4)</string>
       </property>
      </item>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
Changes to jni/zint/frontend_qt4/grpQR.ui.
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
        </property>
       </item>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QGroupBox" name="grpAztecMode">
     <property name="minimumSize">
      <size>
       <width>0</width>
       <height>70</height>
      </size>
     </property>
     <property name="title">







|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
        </property>
       </item>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QGroupBox" name="grpQRMode">
     <property name="minimumSize">
      <size>
       <width>0</width>
       <height>70</height>
      </size>
     </property>
     <property name="title">
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
         <property name="text">
          <string>&amp;GS-1 Data Mode</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
     <zorder>gridLayoutWidget</zorder>
     <zorder></zorder>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>







<
<







325
326
327
328
329
330
331


332
333
334
335
336
337
338
         <property name="text">
          <string>&amp;GS-1 Data Mode</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>


    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>
Changes to jni/zint/frontend_qt4/mainwindow.cpp.
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
		"Australia Post Reply-Paid",
		"Australia Post Routing Code",
		"Australia Post Standard Customer",
		"Aztec Code (ISO 24778)",
		"Aztec Runes",
		"Channel Code",
		"Codabar",

		"Code 11",
		"Code 128 (ISO 15417)",
		"Code 16k",
		"Code 2 of 5 Data Logic",
		"Code 2 of 5 IATA",
		"Code 2 of 5 Industrial",
		"Code 2 of 5 Interleaved",
		"Code 2 of 5 Matrix",
		"Code 32 (Italian Pharmacode)",
		"Code 39 (ISO 16388)",
		"Code 39 Extended",
		"Code 49",
		"Code 93", 
		"Code One",
		"Data Matrix (ISO 16022)",
		"Deutsche Post Identcode",
		"Deutsche Post Leitcode",

		"Dutch Post KIX",
		"EAN-14",
		"European Article Number (EAN)",
		"Facing Identification Mark (FIM)",
		"Flattermarken",
		"Grid Matrix",
		"GS1 DataBar Expanded Omnidirectional",
		"GS1 DataBar Expanded Stacked Omnidirectional",
		"GS1 DataBar Limited",
		"GS1 DataBar Omnidirectional",                
		"GS1 DataBar Stacked",
		"GS1 DataBar Stacked Omnidirectional",                

		"ITF-14",
		"International Standard Book Number (ISBN)",
		"Japanese Postal Barcode",
		"Korean Postal Barcode",
		"LOGMARS",
		"Maxicode (ISO 16023)",
		"MicroPDF417 (ISO 24728)",
		"Micro QR Code",







>

















>












>
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
		"Australia Post Reply-Paid",
		"Australia Post Routing Code",
		"Australia Post Standard Customer",
		"Aztec Code (ISO 24778)",
		"Aztec Runes",
		"Channel Code",
		"Codabar",
                "Codablock-F",
		"Code 11",
		"Code 128 (ISO 15417)",
		"Code 16k",
		"Code 2 of 5 Data Logic",
		"Code 2 of 5 IATA",
		"Code 2 of 5 Industrial",
		"Code 2 of 5 Interleaved",
		"Code 2 of 5 Matrix",
		"Code 32 (Italian Pharmacode)",
		"Code 39 (ISO 16388)",
		"Code 39 Extended",
		"Code 49",
		"Code 93", 
		"Code One",
		"Data Matrix (ISO 16022)",
		"Deutsche Post Identcode",
		"Deutsche Post Leitcode",
                "DotCode",
		"Dutch Post KIX",
		"EAN-14",
		"European Article Number (EAN)",
		"Facing Identification Mark (FIM)",
		"Flattermarken",
		"Grid Matrix",
		"GS1 DataBar Expanded Omnidirectional",
		"GS1 DataBar Expanded Stacked Omnidirectional",
		"GS1 DataBar Limited",
		"GS1 DataBar Omnidirectional",                
		"GS1 DataBar Stacked",
		"GS1 DataBar Stacked Omnidirectional",                
		"Han Xin (Chinese Sensible) Code",
                "ITF-14",
		"International Standard Book Number (ISBN)",
		"Japanese Postal Barcode",
		"Korean Postal Barcode",
		"LOGMARS",
		"Maxicode (ISO 16023)",
		"MicroPDF417 (ISO 24728)",
		"Micro QR Code",
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	
	m_fgcolor=qRgb(0,0,0);
	m_bgcolor=qRgb(0xff,0xff,0xff);
	for (int i=0;i<metaObject()->enumerator(0).keyCount();i++) {
		bstyle->addItem(metaObject()->enumerator(0).key(i));
		bstyle->setItemText(i,bstyle_text[i]);
	}
	bstyle->setCurrentIndex(9);
	change_options();
	update_preview();
	view->scene()->addItem(&m_bc);
	connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(change_options()));
	connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
	connect(heightb, SIGNAL(valueChanged( int )), SLOT(update_preview()));
	connect(bwidth,  SIGNAL(valueChanged( int )), SLOT(update_preview()));







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	
	m_fgcolor=qRgb(0,0,0);
	m_bgcolor=qRgb(0xff,0xff,0xff);
	for (int i=0;i<metaObject()->enumerator(0).keyCount();i++) {
		bstyle->addItem(metaObject()->enumerator(0).key(i));
		bstyle->setItemText(i,bstyle_text[i]);
	}
	bstyle->setCurrentIndex(10);
	change_options();
	update_preview();
	view->scene()->addItem(&m_bc);
	connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(change_options()));
	connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
	connect(heightb, SIGNAL(valueChanged( int )), SLOT(update_preview()));
	connect(bwidth,  SIGNAL(valueChanged( int )), SLOT(update_preview()));
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifdef NO_PNG
	QString fileName = QFileDialog::getSaveFileName(this,
			tr("Save Barcode Image"), ".",
			   tr("Encapsulated Post Script (*.eps);;Scalable Vector Graphic (*.svg)"));
#else
	QString fileName = QFileDialog::getSaveFileName(this,
			tr("Save Barcode Image"), ".",
			   tr("Portable Network Graphic (*.png);;Encapsulated Post Script (*.eps);;Scalable Vector Graphic (*.svg)"));
#endif
	
	if (fileName.isEmpty())
		return false;
	
	status = m_bc.bc.save_to_file(fileName);
	if(status == false) {







|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifdef NO_PNG
	QString fileName = QFileDialog::getSaveFileName(this,
			tr("Save Barcode Image"), ".",
			   tr("Encapsulated Post Script (*.eps);;Scalable Vector Graphic (*.svg)"));
#else
	QString fileName = QFileDialog::getSaveFileName(this,
			tr("Save Barcode Image"), ".",
			   tr("Portable Network Graphic (*.png);;Encapsulated Post Script (*.eps);;Graphics Interchange Format (*.gif);;Scalable Vector Graphic (*.svg);;Windows Bitmap (*.bmp);;ZSoft PC Painter Image (*.pcx)"));
#endif
	
	if (fileName.isEmpty())
		return false;
	
	status = m_bc.bc.save_to_file(fileName);
	if(status == false) {
279
280
281
282
283
284
285














286
287
288
289
290
291
292
			return;
		m_optionWidget=uiload.load(&file);
		file.close();
		tabMain->insertTab(1,m_optionWidget,tr("Micro PDF417"));
		connect(m_optionWidget->findChild<QObject*>("cmbMPDFCols"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radMPDFStand"), SIGNAL(toggled( bool )), SLOT(update_preview()));
	}















	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_AZTEC)
	{
		QFile file(":/grpAztec.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);







>
>
>
>
>
>
>
>
>
>
>
>
>
>







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
			return;
		m_optionWidget=uiload.load(&file);
		file.close();
		tabMain->insertTab(1,m_optionWidget,tr("Micro PDF417"));
		connect(m_optionWidget->findChild<QObject*>("cmbMPDFCols"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radMPDFStand"), SIGNAL(toggled( bool )), SLOT(update_preview()));
	}

    if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DOTCODE)
    {
        QFile file(":/grpDotCode.ui");
        if (!file.open(QIODevice::ReadOnly))
            return;
        m_optionWidget=uiload.load(&file);
        file.close();
        tabMain->insertTab(1,m_optionWidget,tr("DotCode"));
        connect(m_optionWidget->findChild<QObject*>("cmbDotCols"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
        connect(m_optionWidget->findChild<QObject*>("radDotStan"), SIGNAL(clicked( bool )), SLOT(update_preview()));
        connect(m_optionWidget->findChild<QObject*>("radDotGs1"), SIGNAL(clicked( bool )), SLOT(update_preview()));
        connect(m_optionWidget->findChild<QObject*>("txtDotSize"), SIGNAL(textChanged( QString )), SLOT(update_preview()));
    }

	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_AZTEC)
	{
		QFile file(":/grpAztec.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);
345
346
347
348
349
350
351















352
353
354
355
356
357
358
			return;
		m_optionWidget=uiload.load(&file);
		file.close();
		tabMain->insertTab(1,m_optionWidget,tr("Code 16K"));
		connect(m_optionWidget->findChild<QObject*>("radC16kStand"), SIGNAL(toggled( bool )), SLOT(update_preview()));
	}
	















	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DATAMATRIX)
	{
		QFile file(":/grpDM.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);
		file.close();







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
			return;
		m_optionWidget=uiload.load(&file);
		file.close();
		tabMain->insertTab(1,m_optionWidget,tr("Code 16K"));
		connect(m_optionWidget->findChild<QObject*>("radC16kStand"), SIGNAL(toggled( bool )), SLOT(update_preview()));
	}
	
        if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODABLOCKF)
        {
                QFile file (":/grpCodablockF.ui");
                if (!file.open(QIODevice::ReadOnly))
                    return;
                m_optionWidget=uiload.load(&file);
                file.close();
                tabMain->insertTab(1,m_optionWidget,tr("Codablock-F"));
                connect(m_optionWidget->findChild<QObject*>("radCbfAutosize"), SIGNAL(toggled( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("radCbfSetWidth"), SIGNAL(toggled( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("radCbfSetHeight"), SIGNAL(toggled( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("cmbCbfWidth"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("cmbCbfHeight"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
        }
        
	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DATAMATRIX)
	{
		QFile file(":/grpDM.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);
		file.close();
378
379
380
381
382
383
384















385
386
387
388
389
390
391
		connect(m_optionWidget->findChild<QObject*>("radQRECC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("cmbQRSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("cmbQRECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRStand"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRGS1"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
	}
















	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MICROQR)
	{
		QFile file(":/grpMQR.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
		connect(m_optionWidget->findChild<QObject*>("radQRECC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("cmbQRSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("cmbQRECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRStand"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRGS1"), SIGNAL(clicked( bool )), SLOT(update_preview()));
		connect(m_optionWidget->findChild<QObject*>("radQRHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
	}
        
        if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_HANXIN)
        {
                QFile file (":/grpHX.ui");
                if (!file.open(QIODevice::ReadOnly))
                    return;
                m_optionWidget=uiload.load(&file);
                file.close();
                tabMain->insertTab(1,m_optionWidget,tr("Han Xin Code"));
                connect(m_optionWidget->findChild<QObject*>("radHXAuto"), SIGNAL(clicked( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("radHXSize"), SIGNAL(clicked( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("radHXECC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("cmbHXSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
                connect(m_optionWidget->findChild<QObject*>("cmbHXECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
        }

	if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MICROQR)
	{
		QFile file(":/grpMQR.ui");
		if (!file.open(QIODevice::ReadOnly))
			return;
		m_optionWidget=uiload.load(&file);
657
658
659
660
661
662
663








664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
			m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbMPDFCols")->currentIndex());
			if(m_optionWidget->findChild<QRadioButton*>("radMPDFStand")->isChecked())
				m_bc.bc.setSymbol(BARCODE_MICROPDF417);

			if(m_optionWidget->findChild<QRadioButton*>("radMPDFHIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_MICPDF);
			break;









		case BARCODE_AZTEC:
			m_bc.bc.setSymbol(BARCODE_AZTEC);
			if(m_optionWidget->findChild<QRadioButton*>("radAztecSize")->isChecked())
				m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbAztecSize")->currentIndex() + 1);

			if(m_optionWidget->findChild<QRadioButton*>("radAztecECC")->isChecked())
				m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbAztecECC")->currentIndex() + 1);

			if(m_optionWidget->findChild<QRadioButton*>("radAztecGS1")->isChecked())
				m_bc.bc.setInputMode(GS1_MODE);
			if(m_optionWidget->findChild<QRadioButton*>("radAztecHIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_AZTEC);
			break;

		case MSI_PLESSEY:
			m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY);
			m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbMSICheck")->currentIndex());
			break;

		case BARCODE_CODE39:
			if(m_optionWidget->findChild<QRadioButton*>("radC39HIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_39);







>
>
>
>
>
>
>
>















|







704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
			m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbMPDFCols")->currentIndex());
			if(m_optionWidget->findChild<QRadioButton*>("radMPDFStand")->isChecked())
				m_bc.bc.setSymbol(BARCODE_MICROPDF417);

			if(m_optionWidget->findChild<QRadioButton*>("radMPDFHIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_MICPDF);
			break;

        case BARCODE_DOTCODE:
            m_bc.bc.setSymbol(BARCODE_DOTCODE);
            m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbDotCols")->currentIndex());
            if(m_optionWidget->findChild<QRadioButton*>("radDotGs1")->isChecked())
                m_bc.bc.setInputMode(GS1_MODE);
            m_bc.bc.setDotSize(m_optionWidget->findChild<QLineEdit*>("txtDotSize")->text().toFloat());
            break;

		case BARCODE_AZTEC:
			m_bc.bc.setSymbol(BARCODE_AZTEC);
			if(m_optionWidget->findChild<QRadioButton*>("radAztecSize")->isChecked())
				m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbAztecSize")->currentIndex() + 1);

			if(m_optionWidget->findChild<QRadioButton*>("radAztecECC")->isChecked())
				m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbAztecECC")->currentIndex() + 1);

			if(m_optionWidget->findChild<QRadioButton*>("radAztecGS1")->isChecked())
				m_bc.bc.setInputMode(GS1_MODE);
			if(m_optionWidget->findChild<QRadioButton*>("radAztecHIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_AZTEC);
			break;

		case BARCODE_MSI_PLESSEY:
			m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY);
			m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbMSICheck")->currentIndex());
			break;

		case BARCODE_CODE39:
			if(m_optionWidget->findChild<QRadioButton*>("radC39HIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_39);
702
703
704
705
706
707
708









709
710
711
712
713
714
715
			m_bc.bc.setSymbol(BARCODE_CODE16K);
			if(m_optionWidget->findChild<QRadioButton*>("radC16kStand")->isChecked())
				m_bc.bc.setInputMode(UNICODE_MODE);
			else
				m_bc.bc.setInputMode(GS1_MODE);
			break;










		case BARCODE_DATAMATRIX:
			m_bc.bc.setSecurityLevel(1);
			if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_DM);
			else
				m_bc.bc.setSymbol(BARCODE_DATAMATRIX);








>
>
>
>
>
>
>
>
>







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
			m_bc.bc.setSymbol(BARCODE_CODE16K);
			if(m_optionWidget->findChild<QRadioButton*>("radC16kStand")->isChecked())
				m_bc.bc.setInputMode(UNICODE_MODE);
			else
				m_bc.bc.setInputMode(GS1_MODE);
			break;

            case BARCODE_CODABLOCKF:
                m_bc.bc.setSymbol(BARCODE_CODABLOCKF);
                if(m_optionWidget->findChild<QRadioButton*>("radCbfSetWidth")->isChecked())
                    m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbCbfWidth")->currentIndex() + 6);
                // Height selection uses option 1 in zint_symbol
                if(m_optionWidget->findChild<QRadioButton*>("radCbfSetHeight")->isChecked())
                    m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbCbfHeight")->currentIndex() + 1);
                break;
                        
		case BARCODE_DATAMATRIX:
			m_bc.bc.setSecurityLevel(1);
			if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked())
				m_bc.bc.setSymbol(BARCODE_HIBC_DM);
			else
				m_bc.bc.setSymbol(BARCODE_DATAMATRIX);

788
789
790
791
792
793
794
795









796
797
798
799
800
801
802
			break;
			
		case BARCODE_CODE49:
			m_bc.bc.setSymbol(BARCODE_CODE49);
			if(m_optionWidget->findChild<QRadioButton*>("radC49GS1")->isChecked())
				m_bc.bc.setInputMode(GS1_MODE);
			break;
			









		default:
			m_bc.bc.setSymbol(metaObject()->enumerator(0).value(bstyle->currentIndex()));
			break;
	}

	if(chkComposite->isChecked())
		m_bc.bc.setSecurityLevel(cmbCompType->currentIndex());







|
>
>
>
>
>
>
>
>
>







852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
			break;
			
		case BARCODE_CODE49:
			m_bc.bc.setSymbol(BARCODE_CODE49);
			if(m_optionWidget->findChild<QRadioButton*>("radC49GS1")->isChecked())
				m_bc.bc.setInputMode(GS1_MODE);
			break;
                        
                case BARCODE_HANXIN:
                        m_bc.bc.setSymbol(BARCODE_HANXIN);
			if(m_optionWidget->findChild<QRadioButton*>("radHXSize")->isChecked())
				m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbHXSize")->currentIndex() + 1);

			if(m_optionWidget->findChild<QRadioButton*>("radHXECC")->isChecked())
				m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbHXECC")->currentIndex() + 1);
                        break;
                        
		default:
			m_bc.bc.setSymbol(metaObject()->enumerator(0).value(bstyle->currentIndex()));
			break;
	}

	if(chkComposite->isChecked())
		m_bc.bc.setSecurityLevel(cmbCompType->currentIndex());
Changes to jni/zint/frontend_qt4/mainwindow.h.
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
		AUSREPLY	=66,
		AUSROUTE	=67,
		AUSPOST		=63,
		AZTEC		=92,
		AZRUNE		=128,
		CHANNEL		=140,
		CODABAR		=18,

		CODE11		=1,
		CODE128		=20,
		CODE16K		=23,
		C25LOGIC	=6,
		C25IATA		=4,
		C25IND		=7,
		C25INTER	=3,
		C25MATRIX	=2,
		CODE32		=129,
		CODE39		=8,
		EXCODE39	=9,
		CODE49		=24,
		CODE93		=25,
		CODE_ONE	=141,
		DATAMATRIX	=71,
		DPIDENT		=22,
		DPLEIT		=21,

		KIX		=90,
		EAN14		=72,
		EANX		=13,
		FIM		=49,
		FLAT		=28,
		GRIDMATRIX	=142,
		RSS_EXP		=31,
		RSS_EXPSTACK	=81,
		RSS_LTD		=30,
		RSS14		=29,                
		RSS14STACK	=79,
		RSS14STACK_OMNI	=80,                

		ITF14		=89,
		ISBNX		=69,
		JAPANPOST	=76,
		KOREAPOST	=77,
		LOGMARS		=50,
		MAXICODE	=57,
		MICROPDF417	=84,







>

















>











|
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
		AUSREPLY	=66,
		AUSROUTE	=67,
		AUSPOST		=63,
		AZTEC		=92,
		AZRUNE		=128,
		CHANNEL		=140,
		CODABAR		=18,
                CODABLOCK       =74,
		CODE11		=1,
		CODE128		=20,
		CODE16K		=23,
		C25LOGIC	=6,
		C25IATA		=4,
		C25IND		=7,
		C25INTER	=3,
		C25MATRIX	=2,
		CODE32		=129,
		CODE39		=8,
		EXCODE39	=9,
		CODE49		=24,
		CODE93		=25,
		CODE_ONE	=141,
		DATAMATRIX	=71,
		DPIDENT		=22,
		DPLEIT		=21,
                DOTCODE         =115,
		KIX		=90,
		EAN14		=72,
		EANX		=13,
		FIM		=49,
		FLAT		=28,
		GRIDMATRIX	=142,
		RSS_EXP		=31,
		RSS_EXPSTACK	=81,
		RSS_LTD		=30,
		RSS14		=29,                
		RSS14STACK	=79,
		RSS14STACK_OMNI	=80,
                HANXIN          =116,
		ITF14		=89,
		ISBNX		=69,
		JAPANPOST	=76,
		KOREAPOST	=77,
		LOGMARS		=50,
		MAXICODE	=57,
		MICROPDF417	=84,
Changes to jni/zint/frontend_qt4/resources.qrc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
<RCC>
    <qresource prefix="/" >
        <file>images/zoomout.png</file>
        <file>images/rotateleft.png</file>
        <file>images/rotateright.png</file>
        <file>images/zoomin.png</file>
        <file>grpAztec.ui</file>
        <file>grpC39.ui</file>
        <file>grpDM.ui</file>
        <file>grpMSICheck.ui</file>
        <file>grpC128.ui</file>
        <file>grpChannel.ui</file>
        <file>grpMicroPDF.ui</file>
        <file>grpMaxicode.ui</file>
        <file>grpPDF417.ui</file>
        <file>grpC16k.ui</file>
        <file>grpMQR.ui</file>
        <file>grpQR.ui</file>
        <file>grpCodeOne.ui</file>
        <file>grpC49.ui</file>
        <file>grpGrid.ui</file>
	<file>grpDBExtend.ui</file>
        <file>images/zint.png</file>



    </qresource>
</RCC>

|



















|

>
>
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<RCC>
    <qresource prefix="/">
        <file>images/zoomout.png</file>
        <file>images/rotateleft.png</file>
        <file>images/rotateright.png</file>
        <file>images/zoomin.png</file>
        <file>grpAztec.ui</file>
        <file>grpC39.ui</file>
        <file>grpDM.ui</file>
        <file>grpMSICheck.ui</file>
        <file>grpC128.ui</file>
        <file>grpChannel.ui</file>
        <file>grpMicroPDF.ui</file>
        <file>grpMaxicode.ui</file>
        <file>grpPDF417.ui</file>
        <file>grpC16k.ui</file>
        <file>grpMQR.ui</file>
        <file>grpQR.ui</file>
        <file>grpCodeOne.ui</file>
        <file>grpC49.ui</file>
        <file>grpGrid.ui</file>
        <file>grpDBExtend.ui</file>
        <file>images/zint.png</file>
        <file>grpHX.ui</file>
        <file>grpDotCode.ui</file>
        <file>grpCodablockF.ui</file>
    </qresource>
</RCC>
Added jni/zint/win32/libzint.vcxproj.
























































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release_LIB|Win32">
      <Configuration>Release_LIB</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{5C08DC40-8F7D-475E-AA3C-814DED735A4B}</ProjectGuid>
    <RootNamespace>libzint_png_qr</RootNamespace>
    <Keyword>Win32Proj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'" Label="Configuration">
    <ConfigurationType>StaticLibrary</ConfigurationType>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>false</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>false</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>MultiByte</CharacterSet>
    <PlatformToolset>v110</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <AdditionalIncludeDirectories>..\..\..\support\lpng169;..\..\zlib128-dll\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>NO_PNG;WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.4.4";BUILD_ZINT_DLL;ZLIB_DLL;PNG_DLL;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>true</MinimalRebuild>
      <ExceptionHandling />
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
      <SmallerTypeCheck>true</SmallerTypeCheck>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
      <CompileAs>CompileAsCpp</CompileAs>
      <DisableSpecificWarnings>4018;4244;4305;%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <ProjectReference>
      <LinkLibraryDependencies>false</LinkLibraryDependencies>
    </ProjectReference>
    <Link>
      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
      <OutputFile>$(OutDir)zintd.dll</OutputFile>
      <AdditionalLibraryDirectories>..\..\..\support\lpng169\projects\visualc71\Win32_LIB_Debug;..\..\..\support\lpng169\projects\visualc71\Win32_LIB_Debug\ZLib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <IgnoreSpecificDefaultLibraries>libcmtd.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <SubSystem>Windows</SubSystem>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <IntrinsicFunctions>false</IntrinsicFunctions>
      <AdditionalIncludeDirectories>..\..\..\support\lpng169;..\..\zlib128-dll\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.4.4";BUILD_ZINT_DLL;ZLIB_DLL;PNG_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <StringPooling>true</StringPooling>
      <ExceptionHandling />
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat />
      <CompileAs>CompileAsCpp</CompileAs>
      <DisableSpecificWarnings>4018;4244;4305;%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <ProjectReference>
      <LinkLibraryDependencies>false</LinkLibraryDependencies>
    </ProjectReference>
    <Link>
      <AdditionalDependencies>libpng.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <OutputFile>$(OutDir)zint.dll</OutputFile>
      <AdditionalLibraryDirectories>..\..\..\support\lpng169\projects\visualc71\Win32_LIB_Release;..\..\..\support\lpng169\projects\visualc71\Win32_LIB_Release\ZLib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <GenerateDebugInformation>false</GenerateDebugInformation>
      <SubSystem>Windows</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <TargetMachine>MachineX86</TargetMachine>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <IntrinsicFunctions>false</IntrinsicFunctions>
      <AdditionalIncludeDirectories>d:\opt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.4.4";%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <StringPooling>true</StringPooling>
      <ExceptionHandling />
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat />
      <CompileAs>CompileAsCpp</CompileAs>
      <DisableSpecificWarnings>4018;4244;4305;%(DisableSpecificWarnings)</DisableSpecificWarnings>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Lib>
      <OutputFile>$(OutDir)libzintMD.lib</OutputFile>
    </Lib>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="..\backend\2of5.c" />
    <ClCompile Include="..\backend\auspost.c" />
    <ClCompile Include="..\backend\aztec.c" />
    <ClCompile Include="..\backend\bmp.c" />
    <ClCompile Include="..\backend\codablock.c" />
    <ClCompile Include="..\backend\code.c" />
    <ClCompile Include="..\backend\code1.c" />
    <ClCompile Include="..\backend\code128.c" />
    <ClCompile Include="..\backend\code16k.c" />
    <ClCompile Include="..\backend\code49.c" />
    <ClCompile Include="..\backend\common.c" />
    <ClCompile Include="..\backend\composite.c" />
    <ClCompile Include="..\backend\dllversion.c">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="..\backend\dmatrix.c" />
    <ClCompile Include="..\backend\dotcode.c" />
    <ClCompile Include="..\backend\eci.c" />
    <ClCompile Include="..\backend\gif.c" />
    <ClCompile Include="..\backend\gridmtx.c" />
    <ClCompile Include="..\backend\gs1.c" />
    <ClCompile Include="..\backend\hanxin.c" />
    <ClCompile Include="..\backend\imail.c" />
    <ClCompile Include="..\backend\large.c" />
    <ClCompile Include="..\backend\library.c" />
    <ClCompile Include="..\backend\maxicode.c" />
    <ClCompile Include="..\backend\medical.c" />
    <ClCompile Include="..\backend\pcx.c" />
    <ClCompile Include="..\backend\pdf417.c" />
    <ClCompile Include="..\backend\plessey.c" />
    <ClCompile Include="..\backend\png.c" />
    <ClCompile Include="..\backend\postal.c" />
    <ClCompile Include="..\backend\ps.c" />
    <ClCompile Include="..\backend\qr.c" />
    <ClCompile Include="..\backend\raster.c" />
    <ClCompile Include="..\backend\reedsol.c" />
    <ClCompile Include="..\backend\render.c" />
    <ClCompile Include="..\backend\rss.c" />
    <ClCompile Include="..\backend\svg.c" />
    <ClCompile Include="..\backend\telepen.c" />
    <ClCompile Include="..\backend\upcean.c" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\backend\aztec.h" />
    <ClInclude Include="..\backend\code1.h" />
    <ClInclude Include="..\backend\code49.h" />
    <ClInclude Include="..\backend\common.h" />
    <ClInclude Include="..\backend\composite.h" />
    <ClInclude Include="..\backend\dm200.h" />
    <ClInclude Include="..\backend\dmatrix.h" />
    <ClInclude Include="..\backend\font.h" />
    <ClInclude Include="..\backend\gb2312.h" />
    <ClInclude Include="..\backend\gridmtx.h" />
    <ClInclude Include="..\backend\gs1.h" />
    <ClInclude Include="..\backend\large.h" />
    <ClInclude Include="..\backend\maxicode.h" />
    <ClInclude Include="..\backend\maxipng.h" />
    <ClInclude Include="..\backend\ms_stdint.h" />
    <ClInclude Include="..\backend\pdf417.h" />
    <ClInclude Include="..\backend\qr.h" />
    <ClInclude Include="..\backend\reedsol.h" />
    <ClInclude Include="..\backend\resource.h" />
    <ClInclude Include="..\backend\rss.h" />
    <ClInclude Include="..\backend\sjis.h" />
    <ClInclude Include="..\backend\zint.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="..\backend\libzint.rc">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">true</ExcludedFromBuild>
    </ResourceCompile>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>
Changes to jni/zint/win32/zint.sln.
1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008


Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zint", "zint.vcproj", "{3169C7FA-E52C-4BFC-B7BB-E55EBA133770}"
	ProjectSection(ProjectDependencies) = postProject
		{5C08DC40-8F7D-475E-AA3C-814DED735A4B} = {5C08DC40-8F7D-475E-AA3C-814DED735A4B}
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzint", "libzint.vcproj", "{5C08DC40-8F7D-475E-AA3C-814DED735A4B}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Win32 = Debug|Win32
		Release_LIB|Win32 = Release_LIB|Win32
		Release|Win32 = Release|Win32
	EndGlobalSection

|
|
>
>
|
<
<
<

|







1
2
3
4
5
6



7
8
9
10
11
12
13
14
15

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zint", "zint.vcxproj", "{3169C7FA-E52C-4BFC-B7BB-E55EBA133770}"



EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzint", "libzint.vcxproj", "{5C08DC40-8F7D-475E-AA3C-814DED735A4B}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Win32 = Debug|Win32
		Release_LIB|Win32 = Release_LIB|Win32
		Release|Win32 = Release|Win32
	EndGlobalSection
Added jni/zint/win32/zint.vcxproj.


































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release_LIB|Win32">
      <Configuration>Release_LIB</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{3169C7FA-E52C-4BFC-B7BB-E55EBA133770}</ProjectGuid>
    <RootNamespace>zint</RootNamespace>
    <Keyword>Win32Proj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>false</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>false</WholeProgramOptimization>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v120</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">
    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    <IntDir>$(Configuration)\</IntDir>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <AdditionalIncludeDirectories>..\backend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;_WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.3.0";ZINT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>true</MinimalRebuild>
      <ExceptionHandling />
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
      <SmallerTypeCheck>true</SmallerTypeCheck>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
    </ClCompile>
    <Link>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <AdditionalIncludeDirectories>..\backend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;_WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.3.0";ZINT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <StringPooling>true</StringPooling>
      <ExceptionHandling />
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat />
    </ClCompile>
    <Link>
      <AdditionalLibraryDirectories>d:\opt\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_LIB|Win32'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <AdditionalIncludeDirectories>..\backend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>WIN32;_WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ZINT_VERSION="2.3.0";%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <StringPooling>true</StringPooling>
      <ExceptionHandling />
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader />
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat />
    </ClCompile>
    <Link>
      <AdditionalDependencies>libpngMD.lib;zlibMD.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <AdditionalLibraryDirectories>d:\opt\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="..\frontend\getopt.c" />
    <ClCompile Include="..\frontend\getopt1.c" />
    <ClCompile Include="..\frontend\main.c" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\frontend\resource.h" />
    <ClInclude Include="frontend\getopt.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="..\frontend\zint.rc" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="libzint.vcxproj">
      <Project>{5c08dc40-8f7d-475e-aa3c-814ded735a4b}</Project>
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>
Changes to jni/zint/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\backend" /I "..\..\..\lpng" /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ZINT_VERSION="\"2.7.4\"" /YX /FD /D /D /D /D /D /D /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\backend" /I "..\..\..\lpng" /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "NO_PNG" /YX /FD /GZ /D ZINT_VERSION="\"2.7.4\"" /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
95
96
97
98
99
100
101




102
103
104
105
106
107
108
SOURCE=..\..\backend\auspost.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\aztec.c
# End Source File
# Begin Source File





SOURCE=..\..\backend\code.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\code1.c
# End Source File







>
>
>
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
SOURCE=..\..\backend\auspost.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\aztec.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\bmp.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\code.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\code1.c
# End Source File
127
128
129
130
131
132
133








134
135
136
137
138
139
140
141




142
143
144
145
146
147
148
149




150
151
152
153
154
155
156
SOURCE=..\..\backend\composite.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\dmatrix.c
# End Source File
# Begin Source File









SOURCE=..\..\frontend\getopt.c
# End Source File
# Begin Source File

SOURCE=..\..\frontend\getopt1.c
# End Source File
# Begin Source File





SOURCE=..\..\backend\gridmtx.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\gs1.c
# End Source File
# Begin Source File





SOURCE=..\..\backend\imail.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\large.c
# End Source File







>
>
>
>
>
>
>
>








>
>
>
>








>
>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
SOURCE=..\..\backend\composite.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\dmatrix.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\dotcode.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\eci.c
# End Source File
# Begin Source File

SOURCE=..\..\frontend\getopt.c
# End Source File
# Begin Source File

SOURCE=..\..\frontend\getopt1.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\gif.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\gridmtx.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\gs1.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\hanxin.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\imail.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\large.c
# End Source File
167
168
169
170
171
172
173




174
175
176
177
178
179
180
SOURCE=..\..\backend\maxicode.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\medical.c
# End Source File
# Begin Source File





SOURCE=..\..\backend\pdf417.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\plessey.c
# End Source File







>
>
>
>







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
SOURCE=..\..\backend\maxicode.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\medical.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\pcx.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\pdf417.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\plessey.c
# End Source File
191
192
193
194
195
196
197




198
199
200
201
202
203
204
SOURCE=..\..\backend\ps.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\qr.c
# End Source File
# Begin Source File





SOURCE=..\..\backend\reedsol.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\render.c
# End Source File







>
>
>
>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
SOURCE=..\..\backend\ps.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\qr.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\raster.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\reedsol.c
# End Source File
# Begin Source File

SOURCE=..\..\backend\render.c
# End Source File