mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Ultra: Add UCC, Correct ECC calculation for EC0, Expand ECI support to all values
This commit is contained in:
parent
ea6902c817
commit
e6ab17086c
101
backend/ultra.c
101
backend/ultra.c
@ -60,6 +60,10 @@ static const char ultra_colour[] = "WCBMRYGK";
|
|||||||
//static const int ultra_maxsize[] = {34, 78, 158, 282}; // According to Table 1
|
//static const int ultra_maxsize[] = {34, 78, 158, 282}; // According to Table 1
|
||||||
static const int ultra_maxsize[] = {34, 82, 158, 282}; // Adjusted to allow 79-82 codeword range in 3-row symbols
|
static const int ultra_maxsize[] = {34, 82, 158, 282}; // Adjusted to allow 79-82 codeword range in 3-row symbols
|
||||||
|
|
||||||
|
static const int ultra_mincols[] = {5, 13, 23, 30}; // # Total Tile Columns from Table 1
|
||||||
|
|
||||||
|
static const int kec[] = {0, 1, 2, 4, 6, 8}; // Value K(EC) from Table 12
|
||||||
|
|
||||||
static const int dccu[] = {
|
static const int dccu[] = {
|
||||||
051363, 051563, 051653, 053153, 053163, 053513, 053563, 053613, // 0-7
|
051363, 051563, 051653, 053153, 053163, 053513, 053563, 053613, // 0-7
|
||||||
053653, 056153, 056163, 056313, 056353, 056363, 056513, 056563, // 8-15
|
053653, 056153, 056163, 056313, 056353, 056363, 056513, 056563, // 8-15
|
||||||
@ -630,11 +634,27 @@ int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned char sou
|
|||||||
// Avoids ECI 14 for non-existant ISO/IEC 8859-12
|
// Avoids ECI 14 for non-existant ISO/IEC 8859-12
|
||||||
codewords[0]--;
|
codewords[0]--;
|
||||||
}
|
}
|
||||||
} else if (symbol->eci > 18) {
|
} else if ((symbol->eci > 18) && (symbol->eci <= 898)) {
|
||||||
// ECI indicates use of character set outside ISO/IEC 8859
|
// ECI indicates use of character set outside ISO/IEC 8859
|
||||||
codewords[0] = 273 + (symbol->eci / 256);
|
codewords[0] = 273 + (symbol->eci / 256);
|
||||||
codewords[1] = symbol->eci % 256;
|
codewords[1] = symbol->eci % 256;
|
||||||
codeword_count++;
|
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)
|
||||||
|
// 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
|
||||||
|
codewords[2] = (symbol->eci / 100) + 128;
|
||||||
|
codewords[3] = (symbol->eci % 100) + 128;
|
||||||
|
codeword_count += 3;
|
||||||
|
} else if (symbol->eci >= 10000) {
|
||||||
|
// Encode as 4 codewords
|
||||||
|
codewords[0] = 257; // ISO/IEC 8859-1 used to enter 8-bit mode
|
||||||
|
codewords[1] = 275; // Encode ECI as 4 codewords
|
||||||
|
codewords[2] = (symbol->eci / 10000) + 128;
|
||||||
|
codewords[3] = ((symbol->eci % 10000) / 100) + 128;
|
||||||
|
codewords[4] = (symbol->eci % 100) + 128;
|
||||||
|
codeword_count += 4;
|
||||||
} else {
|
} else {
|
||||||
codewords[0] = 257; // Default is assumed to be ISO/IEC 8859-1 (ECI 3)
|
codewords[0] = 257; // Default is assumed to be ISO/IEC 8859-1 (ECI 3)
|
||||||
}
|
}
|
||||||
@ -771,25 +791,29 @@ int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned char sou
|
|||||||
|
|
||||||
int ultracode(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
|
int ultracode(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
|
||||||
int data_cw_count = 0;
|
int data_cw_count = 0;
|
||||||
int ecc_cw; // = Q in section 7.7.1
|
int acc, qcc;
|
||||||
int ecc_level;
|
int ecc_level;
|
||||||
int misdecode_cw; // = P in section 7.7.1
|
|
||||||
int rows, columns;
|
int rows, columns;
|
||||||
int total_cws;
|
int total_cws;
|
||||||
int pads;
|
int pads;
|
||||||
int cw_memalloc;
|
int cw_memalloc;
|
||||||
int codeword[283];
|
int codeword[283];
|
||||||
int i, j, posn;
|
int i, j, posn;
|
||||||
int acc;
|
|
||||||
int total_height, total_width;
|
int total_height, total_width;
|
||||||
char tilepat[6];
|
char tilepat[6];
|
||||||
int tilex, tiley;
|
int tilex, tiley;
|
||||||
|
int dcc;
|
||||||
|
|
||||||
cw_memalloc = in_length * 2;
|
cw_memalloc = in_length * 2;
|
||||||
if (cw_memalloc < 283) {
|
if (cw_memalloc < 283) {
|
||||||
cw_memalloc = 283;
|
cw_memalloc = 283;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol->eci > 811799) {
|
||||||
|
strcpy(symbol->errtxt, "ECI value not supported by Ultracode");
|
||||||
|
return ZINT_ERROR_INVALID_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
int data_codewords[cw_memalloc];
|
int data_codewords[cw_memalloc];
|
||||||
#else
|
#else
|
||||||
@ -798,7 +822,7 @@ int ultracode(struct zint_symbol *symbol, const unsigned char source[], const si
|
|||||||
|
|
||||||
data_cw_count = ultra_generate_codewords(symbol, source, in_length, data_codewords);
|
data_cw_count = ultra_generate_codewords(symbol, source, in_length, data_codewords);
|
||||||
|
|
||||||
//printf("Codewords returned = %d\n", data_cw_count);
|
printf("Codewords returned = %d\n", data_cw_count);
|
||||||
|
|
||||||
//for (int i = 0; i < data_cw_count; i++) {
|
//for (int i = 0; i < data_cw_count; i++) {
|
||||||
// printf("%d ", data_codewords[i]);
|
// printf("%d ", data_codewords[i]);
|
||||||
@ -812,29 +836,28 @@ int ultracode(struct zint_symbol *symbol, const unsigned char source[], const si
|
|||||||
ecc_level = symbol->option_1 - 1;
|
ecc_level = symbol->option_1 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecc_level == 0) {
|
|
||||||
misdecode_cw = 0;
|
|
||||||
} else {
|
|
||||||
misdecode_cw = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ECC calculation from section 7.7.2 */
|
/* ECC calculation from section 7.7.2 */
|
||||||
if ((data_cw_count % 25) == 0) {
|
if (ecc_level == 0) {
|
||||||
ecc_cw = (ecc_level * (data_cw_count / 25)) + misdecode_cw + 2;
|
qcc = 3;
|
||||||
} else {
|
} else {
|
||||||
ecc_cw = (ecc_level * ((data_cw_count / 25) + 1)) + misdecode_cw + 2;
|
if ((data_cw_count % 25) == 0) {
|
||||||
}
|
qcc = (kec[ecc_level] * (data_cw_count / 25)) + 3 + 2;
|
||||||
|
} else {
|
||||||
|
qcc = (kec[ecc_level] * ((data_cw_count / 25) + 1)) + 3 + 2;
|
||||||
|
}
|
||||||
|
|
||||||
//printf("ECC codewords: %d\n", ecc_cw);
|
}
|
||||||
|
acc = qcc - 3;
|
||||||
|
|
||||||
|
printf("ECC codewords: %d\n", qcc);
|
||||||
|
|
||||||
/* Maximum capacity is 282 codewords */
|
/* Maximum capacity is 282 codewords */
|
||||||
if (data_cw_count + ecc_cw > 282) {
|
total_cws = data_cw_count + qcc + 5;
|
||||||
|
if (total_cws > 282) {
|
||||||
strcpy(symbol->errtxt, "Data too long for selected error correction capacity");
|
strcpy(symbol->errtxt, "Data too long for selected error correction capacity");
|
||||||
return ZINT_ERROR_TOO_LONG;
|
return ZINT_ERROR_TOO_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_cws = data_cw_count + ecc_cw + 2 + misdecode_cw;
|
|
||||||
|
|
||||||
rows = 5;
|
rows = 5;
|
||||||
for (i = 2; i >= 0; i--) {
|
for (i = 2; i >= 0; i--) {
|
||||||
if (total_cws < ultra_maxsize[i]) {
|
if (total_cws < ultra_maxsize[i]) {
|
||||||
@ -852,8 +875,6 @@ int ultracode(struct zint_symbol *symbol, const unsigned char source[], const si
|
|||||||
|
|
||||||
printf("Calculated size is %d rows by %d columns\n", rows, columns);
|
printf("Calculated size is %d rows by %d columns\n", rows, columns);
|
||||||
|
|
||||||
acc = ecc_cw - misdecode_cw; // ACC = (Q-P) - section 6.11.6
|
|
||||||
|
|
||||||
/* Insert MCC and ACC into data codewords */
|
/* Insert MCC and ACC into data codewords */
|
||||||
for (i = 282; i > 2; i--) {
|
for (i = 282; i > 2; i--) {
|
||||||
data_codewords[i] = data_codewords[i - 2];
|
data_codewords[i] = data_codewords[i - 2];
|
||||||
@ -861,26 +882,26 @@ int ultracode(struct zint_symbol *symbol, const unsigned char source[], const si
|
|||||||
data_codewords[1] = data_cw_count += 2; // MCC
|
data_codewords[1] = data_cw_count += 2; // MCC
|
||||||
data_codewords[2] = acc; // ACC
|
data_codewords[2] = acc; // ACC
|
||||||
|
|
||||||
|
posn = 0;
|
||||||
/* Calculate error correction codewords (RSEC) */
|
/* Calculate error correction codewords (RSEC) */
|
||||||
ultra_gf283((short) data_cw_count, (short) ecc_cw, data_codewords);
|
ultra_gf283((short) data_cw_count, (short) qcc, data_codewords);
|
||||||
|
|
||||||
/* Rearrange to make final codeword sequence */
|
/* Rearrange to make final codeword sequence */
|
||||||
posn = 0;
|
codeword[posn++] = data_codewords[282 - (data_cw_count + qcc)]; // Start Character
|
||||||
codeword[posn++] = data_codewords[282 - (data_cw_count + ecc_cw)]; // Start Character
|
|
||||||
codeword[posn++] = data_cw_count; // MCC
|
codeword[posn++] = data_cw_count; // MCC
|
||||||
for (i = 0; i < ecc_cw; i++) {
|
for (i = 0; i < qcc; i++) {
|
||||||
codeword[posn++] = data_codewords[(282 - ecc_cw) + i]; // RSEC Region
|
codeword[posn++] = data_codewords[(282 - qcc) + i]; // RSEC Region
|
||||||
}
|
}
|
||||||
codeword[posn++] = data_cw_count + ecc_cw; // TCC = C + Q - section 6.11.4
|
codeword[posn++] = data_cw_count + qcc; // TCC = C + Q - section 6.11.4
|
||||||
codeword[posn++] = 283; // Separator
|
codeword[posn++] = 283; // Separator
|
||||||
codeword[posn++] = acc; // ACC
|
codeword[posn++] = acc; // ACC
|
||||||
for (i = 0; i < (data_cw_count - 3); i++) {
|
for (i = 0; i < (data_cw_count - 3); i++) {
|
||||||
codeword[posn++] = data_codewords[(282 - ((data_cw_count - 3) + ecc_cw)) + i]; // Data Region
|
codeword[posn++] = data_codewords[(282 - ((data_cw_count - 3) + qcc)) + i]; // Data Region
|
||||||
}
|
}
|
||||||
for (i = 0; i < pads; i++) {
|
for (i = 0; i < pads; i++) {
|
||||||
codeword[posn++] = 284; // Pad pattern
|
codeword[posn++] = 284; // Pad pattern
|
||||||
}
|
}
|
||||||
codeword[posn++] = ecc_cw; // QCC
|
codeword[posn++] = qcc; // QCC
|
||||||
|
|
||||||
printf("Rearranged codewords with ECC:\n");
|
printf("Rearranged codewords with ECC:\n");
|
||||||
for (i = 0; i < posn; i++) {
|
for (i = 0; i < posn; i++) {
|
||||||
@ -961,6 +982,28 @@ int ultracode(struct zint_symbol *symbol, const unsigned char source[], const si
|
|||||||
tiley += 6;
|
tiley += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add data column count */
|
||||||
|
dcc = columns - ultra_mincols[rows - 2];
|
||||||
|
tilex = 2;
|
||||||
|
tiley = (total_height - 11) / 2;
|
||||||
|
/* DCCU */
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
tilepat[4 - j] = ultra_colour[(dccu[dcc] >> (3 * j)) & 0x07];
|
||||||
|
}
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
pattern[((tiley + j) * total_width) + tilex] = tilepat[j];
|
||||||
|
}
|
||||||
|
/* DCCL */
|
||||||
|
tiley += 6;
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
tilepat[4 - j] = ultra_colour[(dccl[dcc] >> (3 * j)) & 0x07];
|
||||||
|
}
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
pattern[((tiley + j) * total_width) + tilex] = tilepat[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("DCC: %d\n", dcc);
|
||||||
|
|
||||||
for (i = 0; i < (total_height * total_width); i++) {
|
for (i = 0; i < (total_height * total_width); i++) {
|
||||||
printf("%c", pattern[i]);
|
printf("%c", pattern[i]);
|
||||||
if ((i + 1) % total_width == 0) {
|
if ((i + 1) % total_width == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user