Improved processing of CC-C

This commit is contained in:
Robin Stuart 2016-09-25 11:09:20 +01:00
parent f4ad4a1afd
commit f8b56002c9

View File

@ -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 */