mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Improved processing of CC-C
This commit is contained in:
parent
f4ad4a1afd
commit
f8b56002c9
@ -794,6 +794,238 @@ int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level)
|
|||||||
return 0;
|
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 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 encoding_method, read_posn, d1, d2, value, alpha_pad;
|
||||||
int i, j, mask, ai_crop, fnc1_latch;
|
int i, j, mask, ai_crop, fnc1_latch;
|
||||||
@ -1488,250 +1720,26 @@ int cc_binary_string(struct zint_symbol *symbol, const char source[], char binar
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (i + latch < (int) strlen(general_field));
|
} while (i + latch < (int) strlen(general_field));
|
||||||
|
|
||||||
binary_length = strlen(binary_string);
|
binary_length = strlen(binary_string);
|
||||||
if (cc_mode == 1) {
|
switch (cc_mode) {
|
||||||
/* CC-A 2D component - calculate remaining space */
|
case 1:
|
||||||
switch (*(cc_width)) {
|
target_bitsize = calc_padding_cca(binary_length, *(cc_width));
|
||||||
case 2:
|
break;
|
||||||
if (binary_length > 167) {
|
case 2:
|
||||||
return ZINT_ERROR_TOO_LONG;
|
target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
|
||||||
}
|
break;
|
||||||
if (binary_length <= 167) {
|
case 3:
|
||||||
target_bitsize = 167;
|
target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
|
||||||
}
|
break;
|
||||||
if (binary_length <= 138) {
|
}
|
||||||
target_bitsize = 138;
|
|
||||||
}
|
if (target_bitsize == 0) {
|
||||||
if (binary_length <= 118) {
|
strcpy(symbol->errtxt, "Input too long for selected 2d component");
|
||||||
target_bitsize = 118;
|
return ZINT_ERROR_TOO_LONG;
|
||||||
}
|
|
||||||
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) {
|
remainder = target_bitsize - binary_length;
|
||||||
/* 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) {
|
if (latch == 1) {
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1774,249 +1782,23 @@ int cc_binary_string(struct zint_symbol *symbol, const char source[], char binar
|
|||||||
return ZINT_ERROR_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);
|
binary_length = strlen(binary_string);
|
||||||
if (cc_mode == 1) {
|
switch (cc_mode) {
|
||||||
/* CC-A 2D component - calculate padding required */
|
case 1:
|
||||||
switch (*(cc_width)) {
|
target_bitsize = calc_padding_cca(binary_length, *(cc_width));
|
||||||
case 2:
|
break;
|
||||||
if (binary_length > 167) {
|
case 2:
|
||||||
return ZINT_ERROR_TOO_LONG;
|
target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
|
||||||
}
|
break;
|
||||||
if (binary_length <= 167) {
|
case 3:
|
||||||
target_bitsize = 167;
|
target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
|
||||||
}
|
break;
|
||||||
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) {
|
if (target_bitsize == 0) {
|
||||||
/* CC-B 2D component */
|
strcpy(symbol->errtxt, "Input too long for selected 2d component");
|
||||||
switch (*(cc_width)) {
|
return ZINT_ERROR_TOO_LONG;
|
||||||
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) {
|
if (binary_length < target_bitsize) {
|
||||||
@ -2092,6 +1874,25 @@ void add_leading_zeroes(struct zint_symbol *symbol) {
|
|||||||
symbol->primary[n] = '\0';
|
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 composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||||
int error_number, cc_mode, cc_width, ecc_level;
|
int error_number, cc_mode, cc_width, ecc_level;
|
||||||
int j, i, k;
|
int j, i, k;
|
||||||
@ -2107,7 +1908,9 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
#endif
|
#endif
|
||||||
struct zint_symbol *linear;
|
struct zint_symbol *linear;
|
||||||
int top_shift, bottom_shift;
|
int top_shift, bottom_shift;
|
||||||
|
int linear_width = 0;
|
||||||
|
|
||||||
|
/* Perform sanity checks on input options first */
|
||||||
error_number = 0;
|
error_number = 0;
|
||||||
pri_len = strlen(symbol->primary);
|
pri_len = strlen(symbol->primary);
|
||||||
if (pri_len == 0) {
|
if (pri_len == 0) {
|
||||||
@ -2119,60 +1922,27 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
strcpy(symbol->errtxt, "2D component input data too long");
|
strcpy(symbol->errtxt, "2D component input data too long");
|
||||||
return ZINT_ERROR_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;
|
cc_mode = symbol->option_1;
|
||||||
|
|
||||||
if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) {
|
if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) {
|
||||||
/* CC-C can only be used with a GS1-128 linear part */
|
/* 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)");
|
strcpy(symbol->errtxt, "Invalid mode (CC-C only valid with GS1-128 linear component)");
|
||||||
return ZINT_ERROR_INVALID_OPTION;
|
return ZINT_ERROR_INVALID_OPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
linear->symbology = symbol->symbology;
|
error_number = gs1_verify(symbol, source, length, reduced);
|
||||||
|
|
||||||
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) {
|
if (error_number != 0) {
|
||||||
strcpy(symbol->errtxt, linear->errtxt);
|
|
||||||
strcat(symbol->errtxt, " in linear component");
|
|
||||||
return error_number;
|
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");
|
||||||
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (symbol->symbology) {
|
switch (symbol->symbology) {
|
||||||
/* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
|
/* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
|
||||||
@ -2209,7 +1979,7 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
case BARCODE_RSS_EXPSTACK_CC: cc_width = 4;
|
case BARCODE_RSS_EXPSTACK_CC: cc_width = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(binary_string, 0, bs);
|
memset(binary_string, 0, bs);
|
||||||
|
|
||||||
if (cc_mode < 1 || cc_mode > 3) {
|
if (cc_mode < 1 || cc_mode > 3) {
|
||||||
@ -2217,7 +1987,7 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cc_mode == 1) {
|
if (cc_mode == 1) {
|
||||||
i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width);
|
i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
|
||||||
if (i == ZINT_ERROR_TOO_LONG) {
|
if (i == ZINT_ERROR_TOO_LONG) {
|
||||||
cc_mode = 2;
|
cc_mode = 2;
|
||||||
}
|
}
|
||||||
@ -2225,7 +1995,7 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
|
|
||||||
if (cc_mode == 2) {
|
if (cc_mode == 2) {
|
||||||
/* If the data didn't fit into CC-A it is recalculated for CC-B */
|
/* 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);
|
i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
|
||||||
if (i == ZINT_ERROR_TOO_LONG) {
|
if (i == ZINT_ERROR_TOO_LONG) {
|
||||||
if (symbol->symbology != BARCODE_EAN128_CC) {
|
if (symbol->symbology != BARCODE_EAN128_CC) {
|
||||||
return ZINT_ERROR_TOO_LONG;
|
return ZINT_ERROR_TOO_LONG;
|
||||||
@ -2237,7 +2007,7 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
|
|
||||||
if (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 */
|
/* 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);
|
i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
|
||||||
if (i == ZINT_ERROR_TOO_LONG) {
|
if (i == ZINT_ERROR_TOO_LONG) {
|
||||||
return ZINT_ERROR_TOO_LONG;
|
return ZINT_ERROR_TOO_LONG;
|
||||||
}
|
}
|
||||||
@ -2256,6 +2026,49 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
|||||||
if (error_number != 0) {
|
if (error_number != 0) {
|
||||||
return ZINT_ERROR_ENCODING_PROBLEM;
|
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 */
|
/* Merge the linear component with the 2D component */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user