Use zero-padded field to determine EANX type for composites

This commit is contained in:
gitlost 2019-10-14 22:20:16 +01:00
parent 433046abbf
commit d8b576164f
4 changed files with 143 additions and 21 deletions

View File

@ -53,7 +53,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
#include <assert.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <malloc.h> #include <malloc.h>
#endif #endif
@ -67,6 +66,7 @@
extern int general_rules(char type[]); extern int general_rules(char type[]);
extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length);
extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length);
extern void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]);
extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length);
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length);
@ -151,7 +151,7 @@ static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) {
codeWords[i] = 0; codeWords[i] = 0;
} }
bitlen = (int)strlen(source); bitlen = (int)strlen(source);
for (i = 0; i < 208; i++) { for (i = 0; i < 208; i++) {
local_source[i] = '0'; local_source[i] = '0';
@ -1658,17 +1658,32 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
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 */
case BARCODE_EANX_CC: case BARCODE_EANX_CC:
switch (pri_len) { cc_width = 0;
case 7: /* EAN-8 */ if (pri_len < 20) {
case 10: /* EAN-8 + 2 */ int padded_pri_len;
case 13: /* EAN-8 + 5 */ char padded_pri[20];
padded_pri[0] = '\0';
ean_leading_zeroes(symbol, (unsigned char*) symbol->primary, (unsigned char*) padded_pri);
padded_pri_len = strlen(padded_pri);
if (padded_pri_len <= 7) { /* EAN-8 */
cc_width = 3; cc_width = 3;
break; } else {
case 12: /* EAN-13 */ switch (padded_pri_len) {
case 15: /* EAN-13 + 2 */ case 10: /* EAN-8 + 2 */
case 18: /* EAN-13 + 5 */ case 13: /* EAN-8 + 5 */
cc_width = 4; cc_width = 3;
break; break;
case 12: /* EAN-13 */
case 15: /* EAN-13 + 2 */
case 18: /* EAN-13 + 5 */
cc_width = 4;
break;
}
}
}
if (cc_width == 0) {
strcpy(symbol->errtxt, "449: Invalid length EAN input in linear component");
return ZINT_ERROR_TOO_LONG;
} }
break; break;
case BARCODE_EAN128_CC: cc_width = 4; case BARCODE_EAN128_CC: cc_width = 4;
@ -1789,19 +1804,19 @@ int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
switch (symbol->symbology) { switch (symbol->symbology) {
/* Determine horizontal alignment (according to section 12.3) */ /* Determine horizontal alignment (according to section 12.3) */
case BARCODE_EANX_CC: case BARCODE_EANX_CC:
switch (pri_len) { switch (ustrlen(linear->text)) { /* Use zero-padded length */
case 7: /* EAN-8 */ case 8: /* EAN-8 */
case 10: /* EAN-8 + 2 */ case 11: /* EAN-8 + 2 */
case 13: /* EAN-8 + 5 */ case 14: /* EAN-8 + 5 */
if (cc_mode == 1) { if (cc_mode == 1) {
bottom_shift = 3; bottom_shift = 3;
} else { } else {
bottom_shift = 13; bottom_shift = 13;
} }
break; break;
case 12: /* EAN-13 */ case 13: /* EAN-13 */
case 15: /* EAN-13 + 2 */ case 16: /* EAN-13 + 2 */
case 18: /* EAN-13 + 5 */ case 19: /* EAN-13 + 5 */
bottom_shift = 2; bottom_shift = 2;
break; break;
} }

View File

@ -47,6 +47,7 @@ macro(zint_add_test test_name test_command)
endmacro(zint_add_test) endmacro(zint_add_test)
zint_add_test(channel, test_channel) zint_add_test(channel, test_channel)
zint_add_test(composite, test_composite)
zint_add_test(eci, test_eci) zint_add_test(eci, test_eci)
zint_add_test(imail, test_imail) zint_add_test(imail, test_imail)
zint_add_test(mailmark, test_mailmark) zint_add_test(mailmark, test_mailmark)

View File

@ -0,0 +1,106 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
static void test_eanx_leading_zeroes(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
unsigned char* composite;
int ret;
int expected_rows;
int expected_width;
};
// Vi} :s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_EANX_CC, "1", "[21]A12345678", 0, 8, 72 }, // EAN-8
/* 1*/ { BARCODE_EANX_CC, "12", "[21]A12345678", 0, 8, 72 },
/* 2*/ { BARCODE_EANX_CC, "123", "[21]A12345678", 0, 8, 72 },
/* 3*/ { BARCODE_EANX_CC, "1234", "[21]A12345678", 0, 8, 72 },
/* 4*/ { BARCODE_EANX_CC, "12345", "[21]A12345678", 0, 8, 72 },
/* 5*/ { BARCODE_EANX_CC, "123456", "[21]A12345678", 0, 8, 72 },
/* 6*/ { BARCODE_EANX_CC, "1234567", "[21]A12345678", 0, 8, 72 },
/* 7*/ { BARCODE_EANX_CC, "12345678", "[21]A12345678", 0, 7, 99 }, // EAN-13
/* 8*/ { BARCODE_EANX_CC, "1+12", "[21]A12345678", 0, 8, 101 }, // EAN-8 + EAN-2
/* 9*/ { BARCODE_EANX_CC, "12+12", "[21]A12345678", 0, 8, 101 },
/*10*/ { BARCODE_EANX_CC, "123+12", "[21]A12345678", 0, 8, 101 },
/*11*/ { BARCODE_EANX_CC, "1234+12", "[21]A12345678", 0, 8, 101 },
/*12*/ { BARCODE_EANX_CC, "12345+12", "[21]A12345678", 0, 8, 101 },
/*13*/ { BARCODE_EANX_CC, "123456+12", "[21]A12345678", 0, 8, 101 },
/*14*/ { BARCODE_EANX_CC, "1234567+12", "[21]A12345678", 0, 8, 101 },
/*15*/ { BARCODE_EANX_CC, "12345678+12", "[21]A12345678", 0, 7, 128 }, // EAN-13 + EAN-2
/*16*/ { BARCODE_EANX_CC, "1+123", "[21]A12345678", 0, 8, 128 }, // EAN-8 + EAN-5
/*17*/ { BARCODE_EANX_CC, "12+123", "[21]A12345678", 0, 8, 128 },
/*18*/ { BARCODE_EANX_CC, "123+123", "[21]A12345678", 0, 8, 128 },
/*19*/ { BARCODE_EANX_CC, "1234+123", "[21]A12345678", 0, 8, 128 },
/*20*/ { BARCODE_EANX_CC, "12345+123", "[21]A12345678", 0, 8, 128 },
/*21*/ { BARCODE_EANX_CC, "123456+123", "[21]A12345678", 0, 8, 128 },
/*22*/ { BARCODE_EANX_CC, "1234567+123", "[21]A12345678", 0, 8, 128 },
/*23*/ { BARCODE_EANX_CC, "12345678+123", "[21]A12345678", 0, 7, 155 }, // EAN-13 + EAN-5
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length);
strcpy(symbol->primary, data[i].data);
int composite_length = strlen(data[i].composite);
ret = ZBarcode_Encode(symbol, data[i].composite, composite_length);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_eanx_leading_zeroes();
testReport();
return 0;
}

View File

@ -617,7 +617,7 @@ void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsi
if (first_len <= 7) { if (first_len <= 7) {
zfirst_len = 7; zfirst_len = 7;
} }
if (second_len == 0) { if (second_len == 0 && symbol->symbology == BARCODE_EANX) { /* No composite EAN-2/5 */
if (first_len <= 5) { if (first_len <= 5) {
zfirst_len = 5; zfirst_len = 5;
} }
@ -686,7 +686,7 @@ void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsi
/* Copy adjusted data back to local_source */ /* Copy adjusted data back to local_source */
strcat((char*) local_source, (char*) zfirst_part); strcat((char*) local_source, (char*) zfirst_part);
if (zsecond_len != 0) { if (ustrlen(zsecond_part)) {
strcat((char*) local_source, "+"); strcat((char*) local_source, "+");
strcat((char*) local_source, (char*) zsecond_part); strcat((char*) local_source, (char*) zsecond_part);
} }