diff --git a/backend/dmatrix.c b/backend/dmatrix.c index c1d94872..bb9aa5fe 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -232,15 +232,15 @@ static int dm_isedifact(const unsigned char input, const int gs1) { return (input >= ' ' && input <= '^') && (!gs1 || input != '['); /* Can't encode GS1 FNC1/GS in EDIFACT */ } -static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, const int sourcelen) { +static int dm_p_r_6_2_1(const unsigned char source[], const int length, const int sp) { /* Annex P section (r)(6)(ii)(I) "If one of the three X12 terminator/separator characters first occurs in the yet to be processed data before a non-X12 character..." */ int i; - for (i = position; i < sourcelen && dm_isX12(inputData[i]); i++) { - if (inputData[i] == 13 || inputData[i] == '*' || inputData[i] == '>') { + for (i = sp; i < length && dm_isX12(source[i]); i++) { + if (source[i] == 13 || source[i] == '*' || source[i] == '>') { return 1; } } @@ -248,6 +248,20 @@ static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, con return 0; } +/* Count number of TEXT characters around `sp` between `position` and `length` + - helper to avoid exiting from Base 256 too early if have series of TEXT characters */ +static int dm_text_sp_cnt(const unsigned char source[], const int position, const int length, const int sp) { + int i; + int cnt = 0; + + /* Count from `sp` forward */ + for (i = sp; i < length && dm_istext(source[i]); i++, cnt++); + /* Count backwards from `sp` */ + for (i = sp - 1; i >= position && dm_istext(source[i]); i--, cnt++); + + return cnt; +} + /* Character counts are multiplied by this, so as to be whole integer divisible by 2, 3 and 4 */ #define DM_MULT 12 @@ -269,7 +283,7 @@ static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, con #define DM_MULT_CEIL(n) ((((n) + DM_MULT_MINUS_1) / DM_MULT) * DM_MULT) /* 'look ahead test' from Annex P */ -static int dm_look_ahead_test(const unsigned char inputData[], const int sourcelen, const int position, +static int dm_look_ahead_test(const unsigned char source[], const int length, const int position, const int current_mode, const int mode_arg, const int gs1, const int debug_print) { int ascii_count, c40_count, text_count, x12_count, edf_count, b256_count; int ascii_rnded, c40_rnded, text_rnded, x12_rnded, edf_rnded, b256_rnded; @@ -307,8 +321,8 @@ static int dm_look_ahead_test(const unsigned char inputData[], const int sourcel break; } - for (sp = position; sp < sourcelen; sp++) { - unsigned char c = inputData[sp]; + for (sp = position; sp < length; sp++) { + unsigned char c = source[sp]; int is_extended = c & 0x80; /* ascii ... step (l) */ @@ -407,8 +421,15 @@ static int dm_look_ahead_test(const unsigned char inputData[], const int sourcel cnt_1 = text_count + DM_MULT_1; if (cnt_1 < ascii_count && cnt_1 < b256_count && cnt_1 < edf_count && cnt_1 < x12_count && cnt_1 < c40_count) { - if (debug_print) printf("TEX->"); - return DM_TEXT; /* step (r)(4) */ + /* Adjusted to avoid early exit from Base 256 if have less than break-even sequence of TEXT chars */ + if (current_mode == DM_BASE256 && position + 6 < length + && dm_text_sp_cnt(source, position, length, sp) >= 12) { + if (debug_print) printf("TEX->"); + return DM_TEXT; /* step (r)(4) */ + } else { + if (debug_print) printf("TEX->"); + return DM_TEXT; /* step (r)(4) */ + } } cnt_1 = x12_count + DM_MULT_1; if (cnt_1 < ascii_count && cnt_1 < b256_count && cnt_1 < edf_count && cnt_1 < text_count @@ -423,7 +444,7 @@ static int dm_look_ahead_test(const unsigned char inputData[], const int sourcel return DM_C40; /* step (r)(6)(i) */ } if (c40_count == x12_count) { - if (dm_p_r_6_2_1(inputData, sp, sourcelen) == 1) { + if (dm_p_r_6_2_1(source, length, sp) == 1) { if (debug_print) printf("X12->"); return DM_X12; /* step (r)(6)(ii)(I) */ } @@ -632,6 +653,35 @@ STATIC_UNLESS_ZINT_TEST int dm_update_b256_field_length(unsigned char target[], return tp; } +/* Switch from ASCII or Base 256 to another mode */ +STATIC_UNLESS_ZINT_TEST int dm_switch_mode(const int next_mode, unsigned char target[], int tp, int *b256_start, + const int debug_print) { + switch (next_mode) { + case DM_ASCII: + if (debug_print) printf("ASC "); + break; + case DM_C40: target[tp++] = 230; + if (debug_print) printf("C40 "); + break; + case DM_TEXT: target[tp++] = 239; + if (debug_print) printf("TEX "); + break; + case DM_X12: target[tp++] = 238; + if (debug_print) printf("X12 "); + break; + case DM_EDIFACT: target[tp++] = 240; + if (debug_print) printf("EDI "); + break; + case DM_BASE256: target[tp++] = 231; + *b256_start = tp; + target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */ + if (debug_print) printf("BAS "); + break; + } + + return tp; +} + /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate Supports encoding FNC1 in supporting systems */ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], @@ -796,25 +846,7 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], next_mode = dm_look_ahead_test(source, inputlen, sp, current_mode, 0, gs1, debug_print); if (next_mode != DM_ASCII) { - switch (next_mode) { - case DM_C40: target[tp++] = 230; - if (debug_print) printf("C40 "); - break; - case DM_TEXT: target[tp++] = 239; - if (debug_print) printf("TEX "); - break; - case DM_X12: target[tp++] = 238; - if (debug_print) printf("X12 "); - break; - case DM_EDIFACT: target[tp++] = 240; - if (debug_print) printf("EDI "); - break; - case DM_BASE256: target[tp++] = 231; - b256_start = tp; - target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */ - if (debug_print) printf("BAS "); - break; - } + tp = dm_switch_mode(next_mode, target, tp, &b256_start, debug_print); not_first = 0; } else { if (source[sp] & 0x80) { @@ -988,8 +1020,9 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], const int prn = ((149 * (i + 1)) % 255) + 1; target[i] = (unsigned char) ((target[i] + prn) & 0xFF); } - next_mode = DM_ASCII; - if (debug_print) printf("ASC "); + /* We switch directly here to avoid flipping back to Base 256 due to `dm_text_sp_cnt()` */ + tp = dm_switch_mode(next_mode, target, tp, &b256_start, debug_print); + not_first = 0; } else { if (gs1 == 2 && source[sp] == '[') { target[tp++] = 29; /* GS */ diff --git a/backend/tests/test_dmatrix.c b/backend/tests/test_dmatrix.c index 80d32a68..0c01a75c 100644 --- a/backend/tests/test_dmatrix.c +++ b/backend/tests/test_dmatrix.c @@ -2554,7 +2554,7 @@ static void test_minimize(int index, int debug) { /* 11*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200AAAAAAAAAAAA", -1, 0, 2, "C40 except last ASC" }, /* 12*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200AAAAAAAAAAAAA", -1, 0, 2, "C40 except last 2 ASC" }, /* 13*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\2009", -1, 0, 0, "ASC last 1" }, - /* 14*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\20099", -1, 0, -1, "Switches too early to ASC (EOD), for last 3" }, + /* 14*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\20099", -1, 0, -1, "Worse, switches too early to ASC (EOD), for last 3" }, /* 15*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200999", -1, 0, 0, "" }, /* 16*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\2009999", -1, 0, 0, "" }, /* 17*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\20099999", -1, 0, 0, "" }, @@ -2637,19 +2637,19 @@ static void test_minimize(int index, int debug) { /* 94*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaa\200\200\200", -1, 0, 0, "BAS" }, /* 95*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaa\200\200\200", -1, 0, 0, "BAS" }, /* 96*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaa\200\200\200", -1, 0, 0, "BAS" }, - /* 97*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200", -1, 0, -2, "7 a's, worse - switches to TEX" }, - /* 98*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200", -1, 0, -2, "7 a's end 2 extended, worse - switches to TEX" }, - /* 99*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200", -1, 0, -1, "7 a's end 1 extended, worse - switches to TEX" }, + /* 97*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200", -1, 0, 0, "7 a's, was worse before dm_text_sp_cnt()" }, + /* 98*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200", -1, 0, 0, "7 a's end 2 extended, was worse before dm_text_sp_cnt()" }, + /* 99*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200", -1, 0, 0, "7 a's end 1 extended, was worse before dm_text_sp_cnt()" }, /*100*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa", -1, 0, 0, "7 a's end 0 extended, switches to TEX but same codeword count" }, - /*101*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200\200aaaaaaa\200\200", -1, 0, -2, "7 a's, worse - switches to TEX" }, - /*102*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200\200\200aaaaaaa\200\200", -1, 0, -2, "7 a's, worse - switches to TEX" }, - /*103*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200\200", -1, 0, -2, "7 a's end 4 extended, worse - switches to TEX" }, - /*104*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200\200\200", -1, 0, -2, "7 a's end 5 extended, worse - switches to TEX" }, - /*105*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaa\200\200", -1, 0, -2, "8 a's end 2 extended, worse - switches to TEX" }, - /*106*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaa\200\200\200", -1, 0, -2, "8 a's, worse - switches to TEX" }, - /*107*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaa\200\200\200", -1, 0, -1, "9 a's, worse - switches to TEX" }, - /*108*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaa\200\200\200", -1, 0, -1, "10 a's, worse - switches to TEX" }, - /*109*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaaa\200\200\200", -1, 0, -1, "11 a's, worse - switches to TEX" }, + /*101*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200\200aaaaaaa\200\200", -1, 0, 0, "7 a's, was worse before dm_text_sp_cnt()" }, + /*102*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200\200\200aaaaaaa\200\200", -1, 0, 0, "7 a's, was worse before dm_text_sp_cnt()" }, + /*103*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200\200", -1, 0, 0, "7 a's end 4 extended, was worse before dm_text_sp_cnt()" }, + /*104*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaa\200\200\200\200\200", -1, 0, 0, "7 a's end 5 extended, was worse before dm_text_sp_cnt()" }, + /*105*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaa\200\200", -1, 0, 0, "8 a's end 2 extended, was worse before dm_text_sp_cnt()" }, + /*106*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaa\200\200\200", -1, 0, 0, "8 a's, was worse before dm_text_sp_cnt()" }, + /*107*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaa\200\200\200", -1, 0, 0, "9 a's, was worse before dm_text_sp_cnt()" }, + /*108*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaa\200\200\200", -1, 0, 0, "10 a's, was worse before dm_text_sp_cnt()" }, + /*109*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaaa\200\200\200", -1, 0, 0, "11 a's, was worse before dm_text_sp_cnt()" }, /*110*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaaaa\200\200\200", -1, 0, 0, "12 a's, switches to TEX but same codeword count" }, /*111*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaaaaa\200\200\200", -1, 0, 0, "13 a's, switches to TEX but same codeword count" }, /*112*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaaaaaaaa\200\200\200", -1, 0, 0, "14 a's, switches to TEX but same codeword count" }, @@ -2663,11 +2663,11 @@ static void test_minimize(int index, int debug) { /*120*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200Aaaaaaa\200\200\200", -1, 0, 0, "" }, /*121*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaAaaa\200\200\200", -1, 0, 0, "" }, /*122*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaA\200\200\200", -1, 0, 0, "" }, - /*123*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200Aaaaaaaa\200\200\200", -1, 0, -2, "" }, + /*123*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200Aaaaaaaa\200\200\200", -1, 0, 0, "" }, /*124*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaAaaa\200\200\200", -1, 0, 0, "" }, /*125*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaAa\200\200\200", -1, 0, 0, "" }, - /*126*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaA\200\200\200", -1, 0, -2, "" }, - /*127*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaAa\200\200\200", -1, 0, -2, "" }, + /*126*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaA\200\200\200", -1, 0, 0, "Was worse before dm_text_sp_cnt()" }, + /*127*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200aaaaaaaAa\200\200\200", -1, 0, 0, "Was worse before dm_text_sp_cnt()" }, /*128*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200>\200\200\200", -1, 0, 0, "BAS" }, /*129*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200>>\200\200\200", -1, 0, 0, "BAS" }, /*130*/ { BARCODE_DATAMATRIX, -1, -1, -1, "\200\200\200>>>\200\200\200", -1, 0, 0, "BAS" }, @@ -2701,6 +2701,8 @@ static void test_minimize(int index, int debug) { /*158*/ { BARCODE_DATAMATRIX, GS1_MODE, GS1_GS_SEPARATOR, -1, "\200\200\200[\200\200[\200\200", -1, 0, 0, "" }, /*159*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, -1, "\200\200\200\200[\200\200\200[\200\200", -1, 0, -1, "Stays in ASC after 1st FNC1" }, /*160*/ { BARCODE_DATAMATRIX, GS1_MODE, GS1_GS_SEPARATOR, -1, "\200\200\200\200[\200\200\200[\200\200", -1, 0, 0, "" }, + /*161*/ { BARCODE_DATAMATRIX, -1, -1, -1, "https://example.com/01/09506000134369", -1, 0, 0, "" }, + /*162*/ { BARCODE_DATAMATRIX, -1, -1, -1, "abcdefghi1234FGHIJKLMNabc@@@@@@@@@é", -1, 0, 0, "" }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; diff --git a/backend/tests/test_dmatrix_variant.h b/backend/tests/test_dmatrix_variant.h index a15d8380..68012f6f 100644 --- a/backend/tests/test_dmatrix_variant.h +++ b/backend/tests/test_dmatrix_variant.h @@ -66,15 +66,15 @@ static int dm_isedifact(const unsigned char input, const int gs1) { return (input >= ' ' && input <= '^') && (!gs1 || input != '['); /* Can't encode GS1 FNC1/GS in EDIFACT */ } -static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, const int sourcelen) { +static int dm_p_r_6_2_1(const unsigned char source[], const int length, const int sp) { /* Annex P section (r)(6)(ii)(I) "If one of the three X12 terminator/separator characters first occurs in the yet to be processed data before a non-X12 character..." */ int i; - for (i = position; i < sourcelen && dm_isX12(inputData[i]); i++) { - if (inputData[i] == 13 || inputData[i] == '*' || inputData[i] == '>') { + for (i = sp; i < length && dm_isX12(source[i]); i++) { + if (source[i] == 13 || source[i] == '*' || source[i] == '>') { return 1; } } @@ -82,6 +82,20 @@ static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, con return 0; } +/* Count number of TEXT characters around `sp` between `position` and `length` + - helper to avoid exiting from Base 256 too early if have series of TEXT characters */ +static int dm_text_sp_cnt(const unsigned char source[], const int position, const int length, const int sp) { + int i; + int cnt = 0; + + /* Count from `sp` forward */ + for (i = sp; i < length && dm_istext(source[i]); i++, cnt++); + /* Count backwards from `sp` */ + for (i = sp - 1; i >= position && dm_istext(source[i]); i--, cnt++); + + return cnt; +} + #define DM_MULT 12 #define DM_MULT_1_DIV_2 6 @@ -103,7 +117,7 @@ static int dm_p_r_6_2_1(const unsigned char inputData[], const int position, con #define DM_MULT_MINUS_1 11 #define DM_MULT_CEIL(n) ((((n) + DM_MULT_MINUS_1) / DM_MULT) * DM_MULT) -static int dm_look_ahead_test_variant(const unsigned char inputData[], const int sourcelen, const int position, +static int dm_look_ahead_test_variant(const unsigned char source[], const int length, const int position, const int current_mode, const int mode_arg, const int gs1, const int debug_print, const int variant) { int ascii_count, c40_count, text_count, x12_count, edf_count, b256_count; int ascii_rnded, c40_rnded, text_rnded, x12_rnded, edf_rnded, b256_rnded; @@ -160,8 +174,8 @@ static int dm_look_ahead_test_variant(const unsigned char inputData[], const int break; } - for (sp = position; sp < sourcelen; sp++) { - unsigned char c = inputData[sp]; + for (sp = position; sp < length; sp++) { + unsigned char c = source[sp]; int is_extended = c & 0x80; /* ascii ... step (l) */ @@ -271,8 +285,22 @@ static int dm_look_ahead_test_variant(const unsigned char inputData[], const int cnt_1 = text_count + DM_MULT_1; if (cnt_1 < ascii_count && cnt_1 < b256_count && cnt_1 < edf_count && cnt_1 < x12_count && cnt_1 < c40_count) { - if (debug_print) printf("TEX->"); - return DM_TEXT; /* step (r)(4) */ + if (variant == 1) { + if (current_mode == DM_BASE256 && position + 6 < length) { + int text_sp_cnt = dm_text_sp_cnt(source, position, length, sp); + if (debug_print) printf("text_sp_cnt %d\n", text_sp_cnt); + if (text_sp_cnt >= 12) { + if (debug_print) printf("TEX->"); + return DM_TEXT; /* step (r)(4) */ + } + } else { + if (debug_print) printf("TEX->"); + return DM_TEXT; /* step (r)(4) */ + } + } else { + if (debug_print) printf("TEX->"); + return DM_TEXT; /* step (r)(4) */ + } } cnt_1 = x12_count + DM_MULT_1; if (cnt_1 < ascii_count && cnt_1 < b256_count && cnt_1 < edf_count && cnt_1 < text_count @@ -287,7 +315,7 @@ static int dm_look_ahead_test_variant(const unsigned char inputData[], const int return DM_C40; /* step (r)(6)(i) */ } if (c40_count == x12_count) { - if (dm_p_r_6_2_1(inputData, sp, sourcelen) == 1) { + if (dm_p_r_6_2_1(source, length, sp) == 1) { if (debug_print) printf("X12->"); return DM_X12; /* step (r)(6)(ii)(I) */ } @@ -438,6 +466,8 @@ STATIC_UNLESS_ZINT_TEST int dm_get_symbolsize(struct zint_symbol *symbol, const STATIC_UNLESS_ZINT_TEST int dm_codewords_remaining(struct zint_symbol *symbol, const int tp, const int process_p); STATIC_UNLESS_ZINT_TEST int dm_c40text_cnt(const int current_mode, const int gs1, unsigned char input); STATIC_UNLESS_ZINT_TEST int dm_update_b256_field_length(unsigned char target[], int tp, int b256_start); +STATIC_UNLESS_ZINT_TEST int dm_switch_mode(const int next_mode, unsigned char target[], int tp, int *b256_start, + const int debug_print); /* Version of dm200encode() to check variant look ahead parameters */ static int dm200encode_variant(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], @@ -602,25 +632,7 @@ static int dm200encode_variant(struct zint_symbol *symbol, const unsigned char s next_mode = dm_look_ahead_test_variant(source, inputlen, sp, current_mode, 0, gs1, debug_print, variant); if (next_mode != DM_ASCII) { - switch (next_mode) { - case DM_C40: target[tp++] = 230; - if (debug_print) printf("C40 "); - break; - case DM_TEXT: target[tp++] = 239; - if (debug_print) printf("TEX "); - break; - case DM_X12: target[tp++] = 238; - if (debug_print) printf("X12 "); - break; - case DM_EDIFACT: target[tp++] = 240; - if (debug_print) printf("EDI "); - break; - case DM_BASE256: target[tp++] = 231; - b256_start = tp; - target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */ - if (debug_print) printf("BAS "); - break; - } + tp = dm_switch_mode(next_mode, target, tp, &b256_start, debug_print); not_first = 0; } else { if (source[sp] & 0x80) { @@ -794,8 +806,13 @@ static int dm200encode_variant(struct zint_symbol *symbol, const unsigned char s const int prn = ((149 * (i + 1)) % 255) + 1; target[i] = (unsigned char) ((target[i] + prn) & 0xFF); } - next_mode = DM_ASCII; - if (debug_print) printf("ASC "); + if (variant == 1) { + tp = dm_switch_mode(next_mode, target, tp, &b256_start, debug_print); + not_first = 0; + } else { + next_mode = DM_ASCII; + if (debug_print) printf("ASC "); + } } else { if (gs1 == 2 && source[sp] == '[') { target[tp++] = 29; /* GS */