From 27e211f9d39ebd55fbc36725a9650fc530dbaf50 Mon Sep 17 00:00:00 2001 From: gitlost Date: Mon, 20 Apr 2020 19:17:15 +0100 Subject: [PATCH] ULTRA: C43 latch, shift; double digit; ECI; tests, refresh EMFs --- backend/tests/data/print/emf/code128_aim.emf | Bin 916 -> 936 bytes .../tests/data/print/emf/dotcode_aim_fig7.emf | Bin 1180 -> 1200 bytes backend/tests/data/print/emf/qr_v1_m.emf | Bin 2212 -> 2232 bytes backend/tests/data/print/emf/ultracode_a.emf | Bin 2356 -> 2376 bytes backend/tests/test_ultra.c | 90 +++++++--- backend/ultra.c | 170 +++++++++++------- 6 files changed, 170 insertions(+), 90 deletions(-) diff --git a/backend/tests/data/print/emf/code128_aim.emf b/backend/tests/data/print/emf/code128_aim.emf index 18e06e11567b7c2e7962a626eba4e9c96c4ec9be..8bc9b30fd15f008106c0c836120d1519c72cd836 100644 GIT binary patch delta 25 hcmbQjzJi^Vk%56BXCkXMJuM}Y>cpB1^`a$2H*ey delta 22 dcmZ3%K82l?k%56BVj`Kk)xm;pD=1w;S< diff --git a/backend/tests/data/print/emf/dotcode_aim_fig7.emf b/backend/tests/data/print/emf/dotcode_aim_fig7.emf index b687e6d5eb0f44ab9822992eb9423898cdd1725d..05e65d47a33e2dcd166a5ecea94c2e76b4877179 100644 GIT binary patch delta 44 lcmbQkxq*|Fk%56BXW~KOi4qcw8zvg63jz6PU}KmY3jn|92J`>` delta 22 dcmdnMIfs*#k%56BVj`Kk)hSO7V{1!({P diff --git a/backend/tests/data/print/emf/qr_v1_m.emf b/backend/tests/data/print/emf/qr_v1_m.emf index 443e51e5ba19d5b909eb7b51058ad2e759578213..33041d573e5079bbfc9bc14f04af3551eeafa744 100644 GIT binary patch delta 44 lcmZ1?xI>VYk%56BXW~KOi4qcwJ0=>c3jz6PU}Kmc2LQ$-2Pgml delta 22 dcmdlXxI~bZk%56BVj`Kk)>H~>7O1)Tr@ diff --git a/backend/tests/data/print/emf/ultracode_a.emf b/backend/tests/data/print/emf/ultracode_a.emf index dd807eb0c0323cec98baf4d97bc4e39b872fe22f..94ff63404c9a235bf01591a0db9e5d34d9011ab1 100644 GIT binary patch delta 45 mcmdlYbV7)gk%56BXR;!r@I(m-MvsYx>Ow#PG_W!39tQxgvhv_*)Ok%56BVj`8h1>XPw diff --git a/backend/tests/test_ultra.c b/backend/tests/test_ultra.c index 2d0dc6b9..61127103 100644 --- a/backend/tests/test_ultra.c +++ b/backend/tests/test_ultra.c @@ -65,13 +65,32 @@ static void test_input(void) /* 12*/ { UNICODE_MODE, 9, -1, -1, "βAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0, "(250) 263 226 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65", "249 chars EC2" }, /* 13*/ { UNICODE_MODE, 9, -1, ULTRA_COMPRESSION, "A", 0, "(2) 272 65", "Note ECI ignored and not outputted if ULTRA_COMPRESSION and all ASCII" }, /* 14*/ { UNICODE_MODE, 15, -1, -1, "Ŗ", 0, "(2) 268 170", "" }, - /* 15*/ { GS1_MODE, 0, -1, -1, "[01]03453120000011[17]20121125[10]ABCD1234", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (17)", "AIMD/TSC15032-43 G.6 Invalid [17] 4-digit year used in example" }, - /* 16*/ { GS1_MODE, 0, -1, -1, "[01]03453120000011[17]121125[10]ABCD1234", 0, "(20) 273 129 131 173 159 148 128 128 139 145 140 139 153 138 65 66 67 68 140 162", "Mode: a (34)" }, - /* 17*/ { GS1_MODE, 0, -1, -1, "[17]120508[10]ABCD1234[410]9501101020917", 0, "(21) 273 145 140 133 136 138 65 66 67 68 140 162 272 169 137 178 139 129 130 137 145", "Mode: a (35)" }, - /* 18*/ { GS1_MODE, 0, -1, -1, "[17]120508[10]ABCDEFGHI[410]9501101020917", 0, "(24) 273 145 140 133 136 138 65 66 67 68 69 70 71 72 73 272 169 137 178 139 129 130 137 145", "Mode: a (36)" }, - /* 19*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "ftp://", 0, "(4) 272 280 269 165", "Mode: c (6)" }, - /* 20*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, ".cgi", 0, "(4) 272 280 274 131", "Mode: c (4)" }, - /* 21*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "ftp://a.cgi", 0, "(6) 272 280 269 165 6 107", "Mode: c (11)" }, + /* 15*/ { DATA_MODE, 898, -1, -1, "\001\002\003\004\377", 0, "(7) 278 130 1 2 3 4 255", "" }, + /* 16*/ { DATA_MODE, 899, -1, -1, "\001\002\003\004\377", 0, "(6) 280 1 2 3 4 255", "" }, + /* 17*/ { DATA_MODE, 900, -1, -1, "\001\002\003\004\377", 0, "(9) 257 274 137 128 1 2 3 4 255", "" }, + /* 18*/ { DATA_MODE, 9999, -1, -1, "\001\002\003\004\377", 0, "(9) 257 274 227 227 1 2 3 4 255", "" }, + /* 19*/ { DATA_MODE, 10000, -1, -1, "\001\002\003\004\377", 0, "(10) 257 275 129 128 128 1 2 3 4 255", "" }, + /* 20*/ { DATA_MODE, 811799, -1, -1, "\001\002\003\004\377", 0, "(10) 257 275 209 145 227 1 2 3 4 255", "" }, + /* 21*/ { DATA_MODE, 811800, -1, -1, "\001\002\003\004\377", ZINT_ERROR_INVALID_OPTION, "Error 590: ECI value not supported by Ultracode", "" }, + /* 22*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "123,456,789/12,/3,4,/5//", 0, "(15) 272 140 231 173 234 206 257 140 44 262 242 44 264 47 47", "Mode: a (24)" }, + /* 23*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "HEIMASÍÐA KENNARAHÁSKÓLA ÍSLANDS", 0, "(32) 257 256 46 151 78 210 205 208 258 5 148 28 72 2 167 52 127 193 83 75 211 267 76 65 32", "Mode: cccccc88cccccccccc8888aaa8cccccc (32)" }, + /* 24*/ { UNICODE_MODE, 0, -1, -1, "HEIMASÍÐA KENNARAHÁSKÓLA ÍSLANDS", 0, "(33) 257 72 69 73 77 65 83 205 208 65 32 75 69 78 78 65 82 65 72 193 83 75 211 76 65 32 205", "" }, + /* 25*/ { UNICODE_MODE, 10, -1, ULTRA_COMPRESSION, "אולטרה-קוד1234", 0, "(14) 264 224 229 236 232 248 228 45 247 229 227 267 140 162", "Mode: 8888888888aaaa (14); Figure G.3" }, + /* 26*/ { UNICODE_MODE, 10, -1, -1, "אולטרה-קוד1234", 0, "(15) 264 224 229 236 232 248 228 45 247 229 227 49 50 51 52", "" }, + /* 27*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "https://aimglobal.org/jcrv3tX", 0, "(16) 282 266 1 74 41 19 6 168 270 212 59 106 144 56 265 70", "Mode: c (21); Figure G.4a" }, + /* 28*/ { UNICODE_MODE, 0, -1, -1, "https://aimglobal.org/jcrv3tX", 0, "(22) 282 97 105 109 103 108 111 98 97 108 46 111 114 103 47 106 99 114 118 51 116 88", "" }, + /* 29*/ { GS1_MODE, 0, -1, -1, "[01]03453120000011[17]121125[10]ABCD1234", 0, "(20) 273 129 131 173 159 148 128 128 139 145 140 139 153 138 65 66 67 68 140 162", "Mode: a (34); Figure G.6 uses C43 for 6 of last 7 chars (same codeword count)" }, + /* 30*/ { GS1_MODE, 0, -1, -1, "[17]120508[10]ABCD1234[410]9501101020917", 0, "(21) 273 145 140 133 136 138 65 66 67 68 140 162 272 169 137 178 139 129 130 137 145", "Mode: a (35)" }, + /* 31*/ { GS1_MODE, 0, -1, -1, "[17]120508[10]ABCDEFGHI[410]9501101020917", 0, "(24) 273 145 140 133 136 138 65 66 67 68 69 70 71 72 73 272 169 137 178 139 129 130 137 145", "Mode: a (36)" }, + /* 32*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "ftp://", 0, "(4) 272 278 269 165", "Mode: c (6)" }, + /* 33*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, ".cgi", 0, "(4) 272 278 274 131", "Mode: c (4)" }, + /* 34*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "ftp://a.cgi", 0, "(6) 272 280 269 123 274 131", "Mode: c (11)" }, + /* 35*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "e: file:f.shtml !", 0, "(12) 272 280 30 94 236 235 72 233 39 52 267 250", "Mode: c (17)" }, + /* 36*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "Aaatel:", 0, "(6) 272 280 262 76 6 89", "Mode: c (7)" }, + /* 37*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "Aatel:a", 0, "(6) 272 280 262 76 271 161", "Mode: c (7)" }, + /* 38*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "Atel:aAa", 0, "(8) 272 275 6 89 275 148 0 42", "Mode: c (8)" }, + /* 39*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "tel:AAaa", 0, "(8) 272 275 271 161 6 28 262 118", "Mode: c (8)" }, + /* 40*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "AAaatel:aA", 0, "(10) 272 276 0 42 0 41 118 46 6 156", "Mode: c (10)" }, }; int data_size = sizeof(data) / sizeof(struct item); @@ -236,22 +255,37 @@ static void test_encode(void) "70170613653553116357" "77777777777777777777" }, - /* 6*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "https://aimglobal.org/jcrv3tX", 0, 13, 22, "AIMD/TSC15032-43 Figure G.4a **NOT SAME** different compression", - "7777777777777777777777" - "7057065133563156313037" - "7767051556651331566757" - "7037066611513613331017" - "7717053165666351655767" - "7037035651531533133057" - "7707070707070707070707" - "7067015511111161565017" - "7737036635335356151737" - "7067063111116533366057" - "7737031536633116511717" - "7017063363361363356057" - "7777777777777777777777" + /* 6*/ { UNICODE_MODE, 0, -1, ULTRA_COMPRESSION, "https://aimglobal.org/jcrv3tX", 0, 13, 20, "AIMD/TSC15032-43 Figure G.4a **NOT SAME** different compression; also DCC incorrect in figure", + "77777777777777777777" + "70570655115631563137" + "77670563356513315617" + "70170611665136133337" + "77570565116663516517" + "70370311355315331357" + "77070707070707070707" + "70670113111111615617" + "77370331553353561537" + "70570655311165333157" + "77370311136331165617" + "70170163363613633157" + "77777777777777777777" }, - /* 7*/ { UNICODE_MODE, 0, -1, -1, "A", 0, 13, 13, "Verified against bwipp", + /* 7*/ { GS1_MODE, 0, -1, -1, "[01]03453120000011[17]121125[10]ABCD1234", 0, 13, 23, "AIMD/TSC15032-43 Figure G.6 **NOT SAME** different compression and ECC; also DCC incorrect in figure", + "77777777777777777777777" + "70570616535355353310157" + "77670553116631616667617" + "70370331365353335550567" + "77570563516616556637657" + "70370656335135665360337" + "77070707070707070707077" + "70670161311353355110517" + "77570313153616611667137" + "70170635531563535550357" + "77370516316135616367117" + "70170335533356531510357" + "77777777777777777777777" + }, + /* 8*/ { UNICODE_MODE, 0, -1, -1, "A", 0, 13, 13, "Verified against bwipp", "7777777777777" "7057063335517" "7717035163667" @@ -266,7 +300,7 @@ static void test_encode(void) "7017033536357" "7777777777777" }, - /* 8*/ { UNICODE_MODE, 0, 2, -1, "12345678901234567890123", 0, 13, 25, "Length 23 == 26 MCC (C) with EC1 so 7 ECC by Table 12", + /* 9*/ { UNICODE_MODE, 0, 2, -1, "12345678901234567890123", 0, 13, 25, "Length 23 == 26 MCC (C) with EC1 so 7 ECC by Table 12", "7777777777777777777777777" "7057063655511111111011117" "7767031563666666666766667" @@ -281,7 +315,7 @@ static void test_encode(void) "7017035653363636636036657" "7777777777777777777777777" }, - /* 9*/ { UNICODE_MODE, 0, 1, -1, "1", 0, 13, 11, "Figure 3a min 2-row, EC0; verified against bwipp", + /* 10*/ { UNICODE_MODE, 0, 1, -1, "1", 0, 13, 11, "Figure 3a min 2-row, EC0; verified against bwipp", "77777777777" "70570661517" "77170355667" @@ -296,7 +330,7 @@ static void test_encode(void) "70170365567" "77777777777" }, - /* 10*/ { UNICODE_MODE, 0, 6, -1, "123456789012345678901", 0, 13, 27, "Figure 3a max 2-row, EC5", + /* 11*/ { UNICODE_MODE, 0, 6, -1, "123456789012345678901", 0, 13, 27, "Figure 3a max 2-row, EC5", "777777777777777777777777777" "705706316551651111101111117" "771703535313166666676666667" @@ -311,7 +345,7 @@ static void test_encode(void) "701705553563556363606363637" "777777777777777777777777777" }, - /* 11*/ { UNICODE_MODE, 0, 6, -1, "1234567890123456789012345678901234567890123456789012", 0, 19, 36, "Figure 3b max 3-row, EC5", + /* 12*/ { UNICODE_MODE, 0, 6, -1, "1234567890123456789012345678901234567890123456789012", 0, 19, 36, "Figure 3b max 3-row, EC5", "777777777777777777777777777777777777" "700706363653513111101111111111111117" "770703511165156356676666666666666667" @@ -332,7 +366,7 @@ static void test_encode(void) "700703155555336565303316566653331637" "777777777777777777777777777777777777" }, - /* 12*/ { UNICODE_MODE, 0, 6, -1, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123", 0, 25, 49, "Figure 3c max 4-row, EC5", + /* 13*/ { UNICODE_MODE, 0, 6, -1, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123", 0, 25, 49, "Figure 3c max 4-row, EC5", "7777777777777777777777777777777777777777777777777" "7007061565635135151011111111111111101111111111117" "7707035151513316566766666666666666676666666666667" @@ -359,7 +393,7 @@ static void test_encode(void) "7007016565561165166063366633666336606336663366637" "7777777777777777777777777777777777777777777777777" }, - /* 13*/ { UNICODE_MODE, 0, 6, -1, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 0, 31, 66, "Figure 3d max 5-row, EC5 **NOT SAME** Max columns due to 282 limit is 60 not 61 as shown", + /* 14*/ { UNICODE_MODE, 0, 6, -1, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 0, 31, 66, "Figure 3d max 5-row, EC5 **NOT SAME** Max columns due to 282 limit is 60 not 61 as shown", "777777777777777777777777777777777777777777777777777777777777777777" "700706655166656555306351111111111110111111111111111011111111111117" "770703331611363336575566666666666667666666666666666766666666666667" diff --git a/backend/ultra.c b/backend/ultra.c index 13e8936e..6e4caa31 100644 --- a/backend/ultra.c +++ b/backend/ultra.c @@ -214,6 +214,7 @@ static int ultra_find_fragment(const unsigned char source[], int source_length, for (k = 0; k < (int) strlen(fragment[j]); k++) { if (source[position + k] != fragment[j][k]) { latch = 0; + break; } } } @@ -308,13 +309,13 @@ static float look_ahead_ascii(unsigned char source[], int in_length, int in_locn codeword_count++; i += 2; done = 1; - } else if ((first_digit >= 0) && (first_digit <= 10) && (second_digit == 11)) { + } else if ((first_digit >= 0) && (first_digit <= 9) && (second_digit == 11)) { /* Single digit or decimal point followed by field deliminator */ cw[codeword_count] = first_digit + 248; codeword_count++; i += 2; done = 1; - } else if ((first_digit == 11) && (second_digit >= 0) && (second_digit <= 10)) { + } else if ((first_digit == 11) && (second_digit >= 0) && (second_digit <= 9)) { /* Field deliminator followed by single digit or decimal point */ cw[codeword_count] = second_digit + 259; codeword_count++; @@ -349,36 +350,79 @@ static float look_ahead_ascii(unsigned char source[], int in_length, int in_locn } } -static int get_subset(unsigned char source[], int in_length, int in_locn) { +/* Returns true if should latch to subset other than given `subset` */ +static int c43_should_latch_other(const unsigned char data[], const size_t length, const unsigned int locn, int subset, int gs1) { + unsigned int i, fraglen, predict_window; + int cnt, alt_cnt, fragno; + const char* set = subset == 1 ? ultra_c43_set1 : ultra_c43_set2; + const char* alt_set = subset == 2 ? ultra_c43_set1 : ultra_c43_set2; + + if (locn + 3 > length) { + return 0; + } + predict_window = locn + 3; + + for (i = locn, cnt = 0, alt_cnt = 0; i < predict_window; i++) { + if (data[i] <= 0x1F || data[i] >= 0x7F || (gs1 && data[i] == '[')) { + break; + } + + fragno = ultra_find_fragment(data, length, i); + if (fragno != -1 && fragno != 26) { + fraglen = strlen(fragment[fragno]); + predict_window += fraglen; + if (predict_window > length) { + predict_window = length; + } + i += fraglen - 1; + } else { + if (strchr(set, data[i]) != NULL) { + cnt++; + } + if (strchr(alt_set, data[i]) != NULL) { + alt_cnt++; + } + } + } + + return alt_cnt > cnt; +} + +static int get_subset(unsigned char source[], int in_length, int in_locn, int current_subset) { int fragno; int subset = 0; - if (posn(ultra_c43_set1, source[in_locn]) != -1) { - subset = 1; - } - - if (posn(ultra_c43_set2, source[in_locn]) != -1) { - subset = 2; - } - - if (posn(ultra_c43_set3, source[in_locn]) != -1) { - subset = 3; - } - fragno = ultra_find_fragment(source, in_length, in_locn); if ((fragno != -1) && (fragno != 26)) { subset = 3; + } else if (current_subset == 2) { + if (posn(ultra_c43_set2, source[in_locn]) != -1) { + subset = 2; + } else if (posn(ultra_c43_set1, source[in_locn]) != -1) { + subset = 1; + } + } else { + if (posn(ultra_c43_set1, source[in_locn]) != -1) { + subset = 1; + } else if (posn(ultra_c43_set2, source[in_locn]) != -1) { + subset = 2; + } + } + + if (subset == 0) { + if (posn(ultra_c43_set3, source[in_locn]) != -1) { + subset = 3; + } } return subset; } /* Encode characters in the C43 compaction submode */ -static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int cw[], int* cw_len, int* encoded, int gs1) { +static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int subset, int cw[], int* cw_len, int* encoded, int gs1, int debug) { int codeword_count = 0; int subcodeword_count = 0; int i; - int subset = 0; int fragno; int sublocn = in_locn; int new_subset; @@ -386,7 +430,6 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, int base43_value; int letters_encoded = 0; int pad; - int gs1_latch = 0; #ifndef _MSC_VER int subcw[(in_length + 3) * 2]; @@ -394,12 +437,6 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, int * subcw = (int *) _alloca((in_length + 3) * 2 * sizeof (int)); #endif /* _MSC_VER */ - subset = get_subset(source, in_length, sublocn); - - if (subset == 0) { - return 0.0; - } - if (current_mode == EIGHTBIT_MODE) { /* Check for permissable URL C43 macro sequences, otherwise encode directly */ fragno = ultra_find_fragment(source, in_length, sublocn); @@ -469,6 +506,34 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, unshift_set = subset; do { + /* Check for FNC1 */ + if (gs1 && source[sublocn] == '[') { + break; + } + + new_subset = get_subset(source, in_length, sublocn, subset); + + if (new_subset == 0) { + break; + } + + if ((new_subset != subset) && ((new_subset == 1) || (new_subset == 2))) { + if (c43_should_latch_other(source, in_length, sublocn, subset, gs1)) { + subcw[subcodeword_count] = 42; // Latch to other C43 set + subcodeword_count++; + unshift_set = new_subset; + } else { + subcw[subcodeword_count] = 40; // Shift to other C43 set for 1 char + subcodeword_count++; + subcw[subcodeword_count] = posn(new_subset == 1 ? ultra_c43_set1 : ultra_c43_set2, source[sublocn]); + subcodeword_count++; + sublocn++; + continue; + } + } + + subset = new_subset; + if (subset == 1) { subcw[subcodeword_count] = posn(ultra_c43_set1, source[sublocn]); subcodeword_count++; @@ -507,30 +572,7 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, subset = unshift_set; } - if (sublocn < in_length && sublocn < end_char) { - new_subset = get_subset(source, in_length, sublocn); - - if (((subset == 1) && (new_subset == 2)) && ((source[sublocn] == '.') || (source[sublocn] == ','))) { - /* and characters available in both subsets */ - new_subset = 1; - } - - if ((new_subset != subset) && ((new_subset == 1) || (new_subset == 2))) { - subcw[subcodeword_count] = 42; // Latch to other C43 set - subcodeword_count++; - unshift_set = new_subset; - } - - subset = new_subset; - } - - /* Check for FNC1 */ - if (sublocn < (in_length - 1)) { - if ((source[sublocn + 1] == '[') && gs1) { - gs1_latch = 1; - } - } - } while ((sublocn < in_length) && (sublocn < end_char) && (subset != 0) && (gs1_latch == 0)); + } while ((sublocn < in_length) && (sublocn < end_char)); pad = 3 - (subcodeword_count % 3); if (pad == 3) { @@ -542,6 +584,12 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, subcodeword_count++; } + if (debug & ZINT_DEBUG_PRINT) { + printf("C43 codewords %.*s: (%d)", in_length, source + in_locn, subcodeword_count); + for (i = 0; i < subcodeword_count; i++) printf( " %d", subcw[i]); + printf("\n"); + } + letters_encoded = sublocn - in_locn; if (encoded != NULL) { *encoded = letters_encoded; @@ -555,7 +603,6 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, codeword_count++; } - *cw_len = codeword_count; if (codeword_count == 0) { @@ -573,6 +620,7 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c int input_locn = 0; char symbol_mode; char current_mode; + int subset; float eightbit_score; float ascii_score; float c43_score; @@ -593,13 +641,6 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof (int)); #endif /* _MSC_VER */ - /* Section 7.6.2 indicates that ECI \000003 to \811799 are supported */ - /* but this seems to contradict Table 5 which only shows up to \000898 */ - if (symbol->eci > 898) { - strcpy(symbol->errtxt, "592: ECI value out of range"); - return ZINT_ERROR_INVALID_OPTION; - } - if ((symbol->input_mode & 0x07) == GS1_MODE) { gs1 = 1; } @@ -638,7 +679,7 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c } } else { if ((symbol->eci >= 3) && (symbol->eci <= 18) && (symbol->eci != 14)) { - // ECI indicate use of character set within ISO/IEC 8859 + // ECI indicates use of character set within ISO/IEC 8859 codewords[0] = 257 + (symbol->eci - 3); if (codewords[0] > 267) { // Avoids ECI 14 for non-existant ISO/IEC 8859-12 @@ -646,11 +687,14 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c } } else if ((symbol->eci > 18) && (symbol->eci <= 898)) { // ECI indicates use of character set outside ISO/IEC 8859 - codewords[0] = 273 + (symbol->eci / 256); + codewords[0] = 275 + (symbol->eci / 256); codewords[1] = symbol->eci % 256; codeword_count++; - } else if ((symbol->eci > 898) && (symbol->eci <= 9999)) { - // ECI beyond 898 needs to use fixed length encodable ECI invocation (section 7.6.2) + } else if (symbol->eci == 899) { + // Non-language byte data + codewords[0] = 280; + } else if ((symbol->eci > 899) && (symbol->eci <= 9999)) { + // ECI beyond 899 needs to use fixed length encodable ECI invocation (section 7.6.2) // Encode as 3 codewords codewords[0] = 257; // ISO/IEC 8859-1 used to enter 8-bit mode codewords[1] = 274; // Encode ECI as 3 codewords @@ -727,7 +771,8 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c end_char = input_locn + PREDICT_WINDOW; eightbit_score = look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, end_char, cw_fragment, &fragment_length, gs1); ascii_score = look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, end_char, cw_fragment, &fragment_length, &ascii_encoded, gs1); - c43_score = look_ahead_c43(crop_source, crop_length, input_locn, current_mode, end_char, cw_fragment, &fragment_length, &c43_encoded, gs1); + subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1; + c43_score = look_ahead_c43(crop_source, crop_length, input_locn, current_mode, end_char, subset, cw_fragment, &fragment_length, &c43_encoded, gs1, 0 /*debug*/); mode[input_locn] = 'a'; current_mode = ASCII_MODE; @@ -782,7 +827,8 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c current_mode = ASCII_MODE; break; case 'c': - look_ahead_c43(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, cw_fragment, &fragment_length, NULL, gs1); + subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1; + look_ahead_c43(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, subset, cw_fragment, &fragment_length, NULL, gs1, symbol->debug); /* Substitute temporary latch if possible */ if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 260) && (fragment_length >= 5) && (fragment_length <= 11)) {