1
0
mirror of https://git.code.sf.net/p/zint/code synced 2026-06-10 07:33:43 +00:00

AUSPOST: support Null FCC (DPID all zeroes); TODO: BWIPP support

CODE128: properly fix not switching before FNC1 in 2nd position
  after alpha (commit [7b0767])
PLANET/KIX: adapt POSTNET to cater for both
general: use static strings to save a few bytes (start/stop in
  particular); various other code fiddles
postal: move tables into funcs
This commit is contained in:
gitlost
2026-04-22 21:25:16 +01:00
parent 7f688b9e58
commit b40393723f
24 changed files with 479 additions and 517 deletions
+2 -1
View File
@@ -1,4 +1,4 @@
Version 2.16.0.9 (dev) not released yet (2026-04-18)
Version 2.16.0.9 (dev) not released yet (2026-04-22)
====================================================
**Incompatible changes**
@@ -35,6 +35,7 @@ Changes
(`option_3 = DM_C40_START`) to allow forcing of initial encodation for given
no. (`option_1`) of initial characters, with 0 meaning all
- DATAMATRIX: add manual FNC1 support
- AUSPOST: support Null FCC (DPID all zeroes)
Bugs
----
+2
View File
@@ -90,10 +90,12 @@ static int c25_common(struct zint_symbol *symbol, const unsigned char source[],
d += start_length;
if (is_matrix) {
/* Standard, Data Logic */
for (i = 0; i < length; i++, d += 6) {
memcpy(d, C25MatrixTable[local_source[i] - '0'], 6);
}
} else {
/* IATA, Industrial */
for (i = 0; i < length; i++, d += 10) {
memcpy(d, C25IndustTable[local_source[i] - '0'], 10);
}
+6 -6
View File
@@ -36,15 +36,15 @@
#include "common.h"
#include "gs1.h"
/* Common to Interleaved, and to ITF-14, DP Leitcode, DP Identcode */
INTERNAL int zint_c25_inter_common(struct zint_symbol *symbol, unsigned char source[], int length,
const int checkdigit_option, const int dont_set_height) {
static const char C25InterTable[10][5] = {
{'1','1','3','3','1'}, {'3','1','1','1','3'}, {'1','3','1','1','3'}, {'3','3','1','1','1'},
{'1','1','3','1','3'}, {'3','1','3','1','1'}, {'1','3','3','1','1'}, {'1','1','1','3','3'},
{'3','1','1','3','1'}, {'1','3','1','3','1'}
};
/* Common to Interleaved, and to ITF-14, DP Leitcode, DP Identcode */
INTERNAL int zint_c25_inter_common(struct zint_symbol *symbol, unsigned char source[], int length,
const int checkdigit_option, const int dont_set_height) {
static const char stop_start[5] = { '3','1','1','1','1' }; /* 1st 3 stop, last 4 start */
int i, j, error_number = 0;
char dest[638]; /* 4 + (125 + 1) * 5 + 3 + 1 = 638 */
char *d = dest;
@@ -77,7 +77,7 @@ INTERNAL int zint_c25_inter_common(struct zint_symbol *symbol, unsigned char sou
}
/* Start character */
memcpy(d, "1111", 4);
memcpy(d, stop_start + 1, 4);
d += 4;
for (i = 0; i < length; i += 2) {
@@ -93,7 +93,7 @@ INTERNAL int zint_c25_inter_common(struct zint_symbol *symbol, unsigned char sou
}
/* Stop character */
memcpy(d, "311", 3);
memcpy(d, stop_start, 3);
d += 3;
z_expand(symbol, dest, (int) (d - dest));
+63 -55
View File
@@ -33,36 +33,45 @@
static const char AusGDSET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #";
#define AUS_GDSET_F (IS_NUM_F | IS_UPR_F | IS_LWR_F | IS_SPC_F | IS_HSH_F)
/* The contents of data_pattern conform to the following standard:
0 = Tracker, Ascender and Descender
1 = Tracker and Ascender
2 = Tracker and Descender
3 = Tracker only */
/* N Encoding Table (numeric) */
static const char AusNTable[10][2] = {
{'0','0'}, {'0','1'}, {'0','2'}, {'1','0'}, {'1','1'}, {'1','2'}, {'2','0'}, {'2','1'}, {'2','2'}, {'3','0'}
{ 0,0 }, { 0,1 }, { 0,2 }, { 1,0 }, { 1,1 }, { 1,2 }, { 2,0 }, { 2,1 }, { 2,2 }, { 3,0 }
};
/* C Encoding Table (GDSET) */
static const char AusCTable[64][3] = {
{'2','2','2'}, {'3','0','0'}, {'3','0','1'}, {'3','0','2'}, {'3','1','0'}, {'3','1','1'},
{'3','1','2'}, {'3','2','0'}, {'3','2','1'}, {'3','2','2'}, {'0','0','0'}, {'0','0','1'},
{'0','0','2'}, {'0','1','0'}, {'0','1','1'}, {'0','1','2'}, {'0','2','0'}, {'0','2','1'},
{'0','2','2'}, {'1','0','0'}, {'1','0','1'}, {'1','0','2'}, {'1','1','0'}, {'1','1','1'},
{'1','1','2'}, {'1','2','0'}, {'1','2','1'}, {'1','2','2'}, {'2','0','0'}, {'2','0','1'},
{'2','0','2'}, {'2','1','0'}, {'2','1','1'}, {'2','1','2'}, {'2','2','0'}, {'2','2','1'},
{'0','2','3'}, {'0','3','0'}, {'0','3','1'}, {'0','3','2'}, {'0','3','3'}, {'1','0','3'},
{'1','1','3'}, {'1','2','3'}, {'1','3','0'}, {'1','3','1'}, {'1','3','2'}, {'1','3','3'},
{'2','0','3'}, {'2','1','3'}, {'2','2','3'}, {'2','3','0'}, {'2','3','1'}, {'2','3','2'},
{'2','3','3'}, {'3','0','3'}, {'3','1','3'}, {'3','2','3'}, {'3','3','0'}, {'3','3','1'},
{'3','3','2'}, {'3','3','3'}, {'0','0','3'}, {'0','1','3'}
{ 2,2,2 }, { 3,0,0 }, { 3,0,1 }, { 3,0,2 }, { 3,1,0 }, {3,1,1 },
{ 3,1,2 }, { 3,2,0 }, { 3,2,1 }, { 3,2,2 }, { 0,0,0 }, {0,0,1 },
{ 0,0,2 }, { 0,1,0 }, { 0,1,1 }, { 0,1,2 }, { 0,2,0 }, {0,2,1 },
{ 0,2,2 }, { 1,0,0 }, { 1,0,1 }, { 1,0,2 }, { 1,1,0 }, {1,1,1 },
{ 1,1,2 }, { 1,2,0 }, { 1,2,1 }, { 1,2,2 }, { 2,0,0 }, {2,0,1 },
{ 2,0,2 }, { 2,1,0 }, { 2,1,1 }, { 2,1,2 }, { 2,2,0 }, {2,2,1 },
{ 0,2,3 }, { 0,3,0 }, { 0,3,1 }, { 0,3,2 }, { 0,3,3 }, {1,0,3 },
{ 1,1,3 }, { 1,2,3 }, { 1,3,0 }, { 1,3,1 }, { 1,3,2 }, {1,3,3 },
{ 2,0,3 }, { 2,1,3 }, { 2,2,3 }, { 2,3,0 }, { 2,3,1 }, {2,3,2 },
{ 2,3,3 }, { 3,0,3 }, { 3,1,3 }, { 3,2,3 }, { 3,3,0 }, {3,3,1 },
{ 3,3,2 }, { 3,3,3 }, { 0,0,3 }, { 0,1,3 }
};
/* Bar to Decimal Conversion Table (Reed-Solomon) */
static const char AusBarTable[64][3] = {
{'0','0','0'}, {'0','0','1'}, {'0','0','2'}, {'0','0','3'}, {'0','1','0'}, {'0','1','1'},
{'0','1','2'}, {'0','1','3'}, {'0','2','0'}, {'0','2','1'}, {'0','2','2'}, {'0','2','3'},
{'0','3','0'}, {'0','3','1'}, {'0','3','2'}, {'0','3','3'}, {'1','0','0'}, {'1','0','1'},
{'1','0','2'}, {'1','0','3'}, {'1','1','0'}, {'1','1','1'}, {'1','1','2'}, {'1','1','3'},
{'1','2','0'}, {'1','2','1'}, {'1','2','2'}, {'1','2','3'}, {'1','3','0'}, {'1','3','1'},
{'1','3','2'}, {'1','3','3'}, {'2','0','0'}, {'2','0','1'}, {'2','0','2'}, {'2','0','3'},
{'2','1','0'}, {'2','1','1'}, {'2','1','2'}, {'2','1','3'}, {'2','2','0'}, {'2','2','1'},
{'2','2','2'}, {'2','2','3'}, {'2','3','0'}, {'2','3','1'}, {'2','3','2'}, {'2','3','3'},
{'3','0','0'}, {'3','0','1'}, {'3','0','2'}, {'3','0','3'}, {'3','1','0'}, {'3','1','1'},
{'3','1','2'}, {'3','1','3'}, {'3','2','0'}, {'3','2','1'}, {'3','2','2'}, {'3','2','3'},
{'3','3','0'}, {'3','3','1'}, {'3','3','2'}, {'3','3','3'}
{ 0,0,0 }, { 0,0,1 }, { 0,0,2 }, { 0,0,3 }, { 0,1,0 }, { 0,1,1 },
{ 0,1,2 }, { 0,1,3 }, { 0,2,0 }, { 0,2,1 }, { 0,2,2 }, { 0,2,3 },
{ 0,3,0 }, { 0,3,1 }, { 0,3,2 }, { 0,3,3 }, { 1,0,0 }, { 1,0,1 },
{ 1,0,2 }, { 1,0,3 }, { 1,1,0 }, { 1,1,1 }, { 1,1,2 }, { 1,1,3 },
{ 1,2,0 }, { 1,2,1 }, { 1,2,2 }, { 1,2,3 }, { 1,3,0 }, { 1,3,1 },
{ 1,3,2 }, { 1,3,3 }, { 2,0,0 }, { 2,0,1 }, { 2,0,2 }, { 2,0,3 },
{ 2,1,0 }, { 2,1,1 }, { 2,1,2 }, { 2,1,3 }, { 2,2,0 }, { 2,2,1 },
{ 2,2,2 }, { 2,2,3 }, { 2,3,0 }, { 2,3,1 }, { 2,3,2 }, { 2,3,3 },
{ 3,0,0 }, { 3,0,1 }, { 3,0,2 }, { 3,0,3 }, { 3,1,0 }, { 3,1,1 },
{ 3,1,2 }, { 3,1,3 }, { 3,2,0 }, { 3,2,1 }, { 3,2,2 }, { 3,2,3 },
{ 3,3,0 }, { 3,3,1 }, { 3,3,2 }, { 3,3,3 }
};
#include <assert.h>
@@ -71,7 +80,7 @@ static const char AusBarTable[64][3] = {
#include "reedsol.h"
static unsigned char aus_convert_pattern(const char data, const int shift) {
return (data - '0') << shift;
return data << shift;
}
/* Adds Reed-Solomon error correction to auspost */
@@ -104,15 +113,15 @@ INTERNAL int zint_daft_set_height(struct zint_symbol *symbol, const float min_he
/* Handles Australia Posts's 4 State Codes */
INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Customer Standard Barcode, Barcode 2 or Barcode 3 system determined automatically
(i.e. the FCC doesn't need to be specified by the user) dependent
/* Standard Customer Barcode, Customer Barcode 2 or Customer Barcode 3 system determined automatically
(i.e. the Format Control Code (FCC) doesn't need to be specified by the user) dependent
on the length of the input string */
static const unsigned char fccs[7][2] = {
/* Null Standard Barcode 2 Barcode 3 Reply Route Redirect */
{ '0','0' }, { '1','1' }, { '5','9' }, { '6','2' }, { '4','5' }, { '8','7' }, { '9','2' }
};
static const char start_stop[2] = { 1,3 };
/* The contents of data_pattern conform to the following standard:
0 = Tracker, Ascender and Descender
1 = Tracker and Ascender
2 = Tracker and Descender
3 = Tracker only */
int i;
int error_number;
int writer;
@@ -121,7 +130,7 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
char data_pattern[200];
char *d = data_pattern;
unsigned char fcc[2] = {0}; /* Suppress clang-tidy warning clang-analyzer-core.UndefinedBinaryOperatorResult */
int fcc_idx; /* Index into `fccs[]` */
unsigned char local_source[30];
int zeroes = 0;
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
@@ -150,13 +159,13 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
/* Format control code (FCC) */
switch (length) {
case 8:
memcpy(fcc, "11", 2);
fcc_idx = 1; /* FCC 11 Standard Customer */
break;
case 13:
memcpy(fcc, "59", 2);
fcc_idx = 2; /* FCC 59 Customer 2 */
break;
case 16:
memcpy(fcc, "59", 2);
fcc_idx = 2; /* FCC 59 Customer 2 */
if ((i = z_not_sane(NEON_F, source, length))) {
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 402,
"Invalid character at position %d in input (digits only for FCC 59 length 16)",
@@ -164,10 +173,10 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
}
break;
case 18:
memcpy(fcc, "62", 2);
fcc_idx = 3; /* FCC 62 Customer 3 */
break;
case 23:
memcpy(fcc, "62", 2);
fcc_idx = 3; /* FCC 62 Customer 3 */
if ((i = z_not_sane(NEON_F, source, length))) {
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 406,
"Invalid character at position %d in input (digits only for FCC 62 length 23)",
@@ -175,12 +184,13 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
}
break;
}
} else {
switch (symbol->symbology) {
case BARCODE_AUSREPLY: memcpy(fcc, "45", 2); break;
case BARCODE_AUSROUTE: memcpy(fcc, "87", 2); break;
case BARCODE_AUSREDIRECT: memcpy(fcc, "92", 2); break;
/* Check if DPID all zeros (Null) */
for (i = 0; i < 8 && source[i] == '0'; i++);
if (i == 8) {
fcc_idx = 0; /* Null */
}
} else {
fcc_idx = symbol->symbology - BARCODE_AUSREPLY + 4; /* 4 (FCC 45), 5 (FCC 87) or 6 (FCC 92) */
/* Add leading zeros as required */
zeroes = 8 - length;
@@ -188,7 +198,7 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
}
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("AUSPOST FCC: %.2s\n", fcc);
printf("AUSPOST FCC: %.2s\n", fccs[fcc_idx]);
}
memcpy(local_source + zeroes, source, length);
@@ -201,12 +211,12 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
}
/* Start character */
memcpy(d, "13", 2);
memcpy(d, start_stop, 2);
d += 2;
/* Encode the FCC */
for (reader = 0; reader < 2; reader++, d += 2) {
memcpy(d, AusNTable[fcc[reader] - '0'], 2);
memcpy(d, AusNTable[fccs[fcc_idx][reader] - '0'], 2);
}
/* Delivery Point Identifier (DPID) */
@@ -233,7 +243,7 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
case 22:
case 37:
case 52:
*d++ = '3';
*d++ = 3;
break;
default:
break;
@@ -243,22 +253,22 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
d = aus_rs_error(data_pattern, d);
/* Stop character */
memcpy(d, "13", 2);
memcpy(d, start_stop, 2);
d += 2;
/* Turn the symbol into a bar pattern ready for plotting */
writer = 0;
h = (int) (d - data_pattern);
for (loopey = 0; loopey < h; loopey++) {
if (data_pattern[loopey] == '1' || data_pattern[loopey] == '0') {
for (loopey = 0, writer = 0; loopey < h; loopey++, writer += 2) {
if (data_pattern[loopey] == 1 || data_pattern[loopey] == 0) {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
if (data_pattern[loopey] == '2' || data_pattern[loopey] == '0') {
if (data_pattern[loopey] == 2 || data_pattern[loopey] == 0) {
z_set_module(symbol, 2, writer);
}
writer += 2;
}
symbol->rows = 3; /* Not stackable */
symbol->width = writer - 1;
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* Australia Post Customer Barcoding Technical Specifications (Revised Aug 2012) Dimensions, placement and
@@ -278,10 +288,8 @@ INTERNAL int zint_auspost(struct zint_symbol *symbol, unsigned char source[], in
symbol->row_height[1] = 2.0f;
error_number = zint_daft_set_height(symbol, 0.0f, 0.0f);
}
symbol->rows = 3; /* Not stackable */
symbol->width = writer - 1;
if (content_segs && z_ct_cpy_cat(symbol, fcc, 2, '\xFF' /*separator (none)*/, local_source, length)) {
if (content_segs && z_ct_cpy_cat(symbol, fccs[fcc_idx], 2, '\xFF' /*separator (none)*/, local_source, length)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
}
+3 -2
View File
@@ -66,6 +66,7 @@ static const char BC412Table[35][8] = {
};
INTERNAL int zint_bc412(struct zint_symbol *symbol, unsigned char source[], int length) { /* IBM BC412 */
static const char stop_start[4] = { '1','1','1','2' }; /* 1st 3 stop, last 2 start */
unsigned char padded_source[20];
int posns[35];
int i, counter_odd = 0, counter_even = 0, check_sum = 0;
@@ -119,7 +120,7 @@ INTERNAL int zint_bc412(struct zint_symbol *symbol, unsigned char source[], int
posns[1] = check_sum;
/* Start character */
memcpy(d, "12", 2);
memcpy(d, stop_start + 2, 2);
d += 2;
for (i = 0; i <= length; i++, d += 8) {
@@ -127,7 +128,7 @@ INTERNAL int zint_bc412(struct zint_symbol *symbol, unsigned char source[], int
}
/* Stop character */
memcpy(d, "111", 3);
memcpy(d, stop_start, 3);
d += 3;
z_expand(symbol, dest, (int) (d - dest));
+3 -2
View File
@@ -175,7 +175,8 @@ nb0: if (++B[0] <= bmax[0]) goto lb0;
/* Channel Code - According to ANSI/AIM BC12-1998 */
INTERNAL int zint_channel(struct zint_symbol *symbol, unsigned char source[], int length) {
static const int max_ranges[] = { -1, -1, -1, 26, 292, 3493, 44072, 576688, 7742862 };
static const unsigned char zeroes_str[] = "0000000"; /* 7 zeroes */
static const unsigned char zeroes_str[7] = { '0','0','0','0','0','0','0' };
static const char finder_pattern[9] = { '1','1','1','1','1','1','1','1','1' };
int S[8] = {0}, B[8] = {0};
int target_value;
char dest[30];
@@ -233,7 +234,7 @@ INTERNAL int zint_channel(struct zint_symbol *symbol, unsigned char source[], in
CHNCHR(channels, target_value, B, S);
memcpy(d, "111111111", 9); /* Finder pattern */
memcpy(d, finder_pattern, 9); /* Finder pattern */
d += 9;
for (i = 8 - channels; i < 8; i++) {
*d++ = z_itoc(S[i]);
+2 -1
View File
@@ -535,6 +535,7 @@ static void SumASCII(uchar **ppOutPos, const int Sum, const int CharacterSet) {
/* Main function called by zint framework
*/
INTERNAL int zint_codablockf(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char stop[7] = { '2','3','3','1','1','1','2' }; /* Stop character */
int charCur, dataLength;
int error_number;
int rows, columns, useColumns;
@@ -859,7 +860,7 @@ INTERNAL int zint_codablockf(struct zint_symbol *symbol, unsigned char source[],
for (c = 0; c < columns - 1; c++, d += 6) {
memcpy(d, zint_C128Table[pOutput[rc + c]], 6);
}
memcpy(d, "2331112", 7); /* Stop character (106, not in `zint_C128Table[]`) */
memcpy(d, stop, 7); /* Stop character (106, not in `zint_C128Table[]`) */
d += 7;
z_expand(symbol, dest, (int) (d - dest));
}
+51 -54
View File
@@ -1,4 +1,4 @@
/* code.c - Handles Code 39, 39+, 93 and VIN */
/* code.c - Handles Code 39 (incl. LOGMARS & HIBC), Extended Code 39 (39+), Code 93 and VIN */
/*
libzint - the open source barcode library
Copyright (C) 2008-2026 Robin Stuart <rstuart114@gmail.com>
@@ -68,56 +68,6 @@ static const char C39Table[43 + 1][10] = {
{'1','2','1','1','2','1','2','1','1','1'} /* Start character (full 10), Stop character (first 9) */
};
/* Encoding the full ASCII character set in Code 39 (ISO/IEC 16388:2007 Table A.2) */
static const char EC39Ctrl[128][2] = {
{'%','U'}, {'$','A'}, {'$','B'}, {'$','C'}, {'$','D'}, {'$','E'}, {'$','F'}, {'$','G'}, {'$','H'}, {'$','I'},
{'$','J'}, {'$','K'}, {'$','L'}, {'$','M'}, {'$','N'}, {'$','O'}, {'$','P'}, {'$','Q'}, {'$','R'}, {'$','S'},
{'$','T'}, {'$','U'}, {'$','V'}, {'$','W'}, {'$','X'}, {'$','Y'}, {'$','Z'}, {'%','A'}, {'%','B'}, {'%','C'},
{'%','D'}, {'%','E'}, { " " }, {'/','A'}, {'/','B'}, {'/','C'}, {'/','D'}, {'/','E'}, {'/','F'}, {'/','G'},
{'/','H'}, {'/','I'}, {'/','J'}, {'/','K'}, {'/','L'}, { "-" }, { "." }, {'/','O'}, { "0" }, { "1" },
{ "2" }, { "3" }, { "4" }, { "5" }, { "6" }, { "7" }, { "8" }, { "9" }, {'/','Z'}, {'%','F'},
{'%','G'}, {'%','H'}, {'%','I'}, {'%','J'}, {'%','V'}, { "A" }, { "B" }, { "C" }, { "D" }, { "E" },
{ "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" },
{ "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" },
{ "Z" }, {'%','K'}, {'%','L'}, {'%','M'}, {'%','N'}, {'%','O'}, {'%','W'}, {'+','A'}, {'+','B'}, {'+','C'},
{'+','D'}, {'+','E'}, {'+','F'}, {'+','G'}, {'+','H'}, {'+','I'}, {'+','J'}, {'+','K'}, {'+','L'}, {'+','M'},
{'+','N'}, {'+','O'}, {'+','P'}, {'+','Q'}, {'+','R'}, {'+','S'}, {'+','T'}, {'+','U'}, {'+','V'}, {'+','W'},
{'+','X'}, {'+','Y'}, {'+','Z'}, {'%','P'}, {'%','Q'}, {'%','R'}, {'%','S'}, {'%','T'}
};
/* Code 93 ANSI/AIM BC5-1995 Table 3 */
static const char C93Ctrl[128][2] = {
{'b','U'}, {'a','A'}, {'a','B'}, {'a','C'}, {'a','D'}, {'a','E'}, {'a','F'}, {'a','G'}, {'a','H'}, {'a','I'},
{'a','J'}, {'a','K'}, {'a','L'}, {'a','M'}, {'a','N'}, {'a','O'}, {'a','P'}, {'a','Q'}, {'a','R'}, {'a','S'},
{'a','T'}, {'a','U'}, {'a','V'}, {'a','W'}, {'a','X'}, {'a','Y'}, {'a','Z'}, {'b','A'}, {'b','B'}, {'b','C'},
{'b','D'}, {'b','E'}, { " " }, {'c','A'}, {'c','B'}, {'c','C'}, { "$" }, { "%" }, {'c','F'}, {'c','G'},
{'c','H'}, {'c','I'}, {'c','J'}, { "+" }, {'c','L'}, { "-" }, { "." }, { "/" }, { "0" }, { "1" },
{ "2" }, { "3" }, { "4" }, { "5" }, { "6" }, { "7" }, { "8" }, { "9" }, {'c','Z'}, {'b','F'},
{'b','G'}, {'b','H'}, {'b','I'}, {'b','J'}, {'b','V'}, { "A" }, { "B" }, { "C" }, { "D" }, { "E" },
{ "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" },
{ "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" },
{ "Z" }, {'b','K'}, {'b','L'}, {'b','M'}, {'b','N'}, {'b','O'}, {'b','W'}, {'d','A'}, {'d','B'}, {'d','C'},
{'d','D'}, {'d','E'}, {'d','F'}, {'d','G'}, {'d','H'}, {'d','I'}, {'d','J'}, {'d','K'}, {'d','L'}, {'d','M'},
{'d','N'}, {'d','O'}, {'d','P'}, {'d','Q'}, {'d','R'}, {'d','S'}, {'d','T'}, {'d','U'}, {'d','V'}, {'d','W'},
{'d','X'}, {'d','Y'}, {'d','Z'}, {'b','P'}, {'b','Q'}, {'b','R'}, {'b','S'}, {'b','T'}
};
/* Code 93 ANSI/AIM BC5-1995 Table 2 */
static const char C93Table[47][6] = {
{'1','3','1','1','1','2'}, {'1','1','1','2','1','3'}, {'1','1','1','3','1','2'}, {'1','1','1','4','1','1'},
{'1','2','1','1','1','3'}, {'1','2','1','2','1','2'}, {'1','2','1','3','1','1'}, {'1','1','1','1','1','4'},
{'1','3','1','2','1','1'}, {'1','4','1','1','1','1'}, {'2','1','1','1','1','3'}, {'2','1','1','2','1','2'},
{'2','1','1','3','1','1'}, {'2','2','1','1','1','2'}, {'2','2','1','2','1','1'}, {'2','3','1','1','1','1'},
{'1','1','2','1','1','3'}, {'1','1','2','2','1','2'}, {'1','1','2','3','1','1'}, {'1','2','2','1','1','2'},
{'1','3','2','1','1','1'}, {'1','1','1','1','2','3'}, {'1','1','1','2','2','2'}, {'1','1','1','3','2','1'},
{'1','2','1','1','2','2'}, {'1','3','1','1','2','1'}, {'2','1','2','1','1','2'}, {'2','1','2','2','1','1'},
{'2','1','1','1','2','2'}, {'2','1','1','2','2','1'}, {'2','2','1','1','2','1'}, {'2','2','2','1','1','1'},
{'1','1','2','1','2','2'}, {'1','1','2','2','2','1'}, {'1','2','2','1','2','1'}, {'1','2','3','1','1','1'},
{'1','2','1','1','3','1'}, {'3','1','1','1','1','2'}, {'3','1','1','2','1','1'}, {'3','2','1','1','1','1'},
{'1','1','2','1','3','1'}, {'1','1','3','1','2','1'}, {'2','1','1','1','3','1'}, {'1','2','1','2','2','1'},
{'3','1','2','1','1','1'}, {'3','1','1','1','2','1'}, {'1','2','2','2','1','1'}
};
/* Code 39 */
INTERNAL int zint_code39(struct zint_symbol *symbol, unsigned char source[], int length) {
int i;
@@ -239,6 +189,22 @@ INTERNAL int zint_code39(struct zint_symbol *symbol, unsigned char source[], int
/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
INTERNAL int zint_excode39(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Encoding the full ASCII character set in Code 39 (ISO/IEC 16388:2007 Table A.2) */
static const char EC39Ctrl[128][2] = {
{'%','U'}, {'$','A'}, {'$','B'}, {'$','C'}, {'$','D'}, {'$','E'}, {'$','F'}, {'$','G'}, {'$','H'}, {'$','I'},
{'$','J'}, {'$','K'}, {'$','L'}, {'$','M'}, {'$','N'}, {'$','O'}, {'$','P'}, {'$','Q'}, {'$','R'}, {'$','S'},
{'$','T'}, {'$','U'}, {'$','V'}, {'$','W'}, {'$','X'}, {'$','Y'}, {'$','Z'}, {'%','A'}, {'%','B'}, {'%','C'},
{'%','D'}, {'%','E'}, { " " }, {'/','A'}, {'/','B'}, {'/','C'}, {'/','D'}, {'/','E'}, {'/','F'}, {'/','G'},
{'/','H'}, {'/','I'}, {'/','J'}, {'/','K'}, {'/','L'}, { "-" }, { "." }, {'/','O'}, { "0" }, { "1" },
{ "2" }, { "3" }, { "4" }, { "5" }, { "6" }, { "7" }, { "8" }, { "9" }, {'/','Z'}, {'%','F'},
{'%','G'}, {'%','H'}, {'%','I'}, {'%','J'}, {'%','V'}, { "A" }, { "B" }, { "C" }, { "D" }, { "E" },
{ "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" },
{ "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" },
{ "Z" }, {'%','K'}, {'%','L'}, {'%','M'}, {'%','N'}, {'%','O'}, {'%','W'}, {'+','A'}, {'+','B'}, {'+','C'},
{'+','D'}, {'+','E'}, {'+','F'}, {'+','G'}, {'+','H'}, {'+','I'}, {'+','J'}, {'+','K'}, {'+','L'}, {'+','M'},
{'+','N'}, {'+','O'}, {'+','P'}, {'+','Q'}, {'+','R'}, {'+','S'}, {'+','T'}, {'+','U'}, {'+','V'}, {'+','W'},
{'+','X'}, {'+','Y'}, {'+','Z'}, {'%','P'}, {'%','Q'}, {'%','R'}, {'%','S'}, {'%','T'}
};
int i;
unsigned char buffer[86 * 2 + 1] = {0};
unsigned char *b = buffer;
@@ -308,11 +274,42 @@ INTERNAL int zint_excode39(struct zint_symbol *symbol, unsigned char source[], i
/* Code 93 is an advancement on Code 39 and the definition is a lot tighter */
INTERNAL int zint_code93(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Code 93 ANSI/AIM BC5-1995 Table 2 */
static const char C93Table[47][6] = {
{'1','3','1','1','1','2'}, {'1','1','1','2','1','3'}, {'1','1','1','3','1','2'}, {'1','1','1','4','1','1'},
{'1','2','1','1','1','3'}, {'1','2','1','2','1','2'}, {'1','2','1','3','1','1'}, {'1','1','1','1','1','4'},
{'1','3','1','2','1','1'}, {'1','4','1','1','1','1'}, {'2','1','1','1','1','3'}, {'2','1','1','2','1','2'},
{'2','1','1','3','1','1'}, {'2','2','1','1','1','2'}, {'2','2','1','2','1','1'}, {'2','3','1','1','1','1'},
{'1','1','2','1','1','3'}, {'1','1','2','2','1','2'}, {'1','1','2','3','1','1'}, {'1','2','2','1','1','2'},
{'1','3','2','1','1','1'}, {'1','1','1','1','2','3'}, {'1','1','1','2','2','2'}, {'1','1','1','3','2','1'},
{'1','2','1','1','2','2'}, {'1','3','1','1','2','1'}, {'2','1','2','1','1','2'}, {'2','1','2','2','1','1'},
{'2','1','1','1','2','2'}, {'2','1','1','2','2','1'}, {'2','2','1','1','2','1'}, {'2','2','2','1','1','1'},
{'1','1','2','1','2','2'}, {'1','1','2','2','2','1'}, {'1','2','2','1','2','1'}, {'1','2','3','1','1','1'},
{'1','2','1','1','3','1'}, {'3','1','1','1','1','2'}, {'3','1','1','2','1','1'}, {'3','2','1','1','1','1'},
{'1','1','2','1','3','1'}, {'1','1','3','1','2','1'}, {'2','1','1','1','3','1'}, {'1','2','1','2','2','1'},
{'3','1','2','1','1','1'}, {'3','1','1','1','2','1'}, {'1','2','2','2','1','1'}
};
/* Code 93 ANSI/AIM BC5-1995 Table 3 */
static const char C93Ctrl[128][2] = {
{'b','U'}, {'a','A'}, {'a','B'}, {'a','C'}, {'a','D'}, {'a','E'}, {'a','F'}, {'a','G'}, {'a','H'}, {'a','I'},
{'a','J'}, {'a','K'}, {'a','L'}, {'a','M'}, {'a','N'}, {'a','O'}, {'a','P'}, {'a','Q'}, {'a','R'}, {'a','S'},
{'a','T'}, {'a','U'}, {'a','V'}, {'a','W'}, {'a','X'}, {'a','Y'}, {'a','Z'}, {'b','A'}, {'b','B'}, {'b','C'},
{'b','D'}, {'b','E'}, { " " }, {'c','A'}, {'c','B'}, {'c','C'}, { "$" }, { "%" }, {'c','F'}, {'c','G'},
{'c','H'}, {'c','I'}, {'c','J'}, { "+" }, {'c','L'}, { "-" }, { "." }, { "/" }, { "0" }, { "1" },
{ "2" }, { "3" }, { "4" }, { "5" }, { "6" }, { "7" }, { "8" }, { "9" }, {'c','Z'}, {'b','F'},
{'b','G'}, {'b','H'}, {'b','I'}, {'b','J'}, {'b','V'}, { "A" }, { "B" }, { "C" }, { "D" }, { "E" },
{ "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" },
{ "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" },
{ "Z" }, {'b','K'}, {'b','L'}, {'b','M'}, {'b','N'}, {'b','O'}, {'b','W'}, {'d','A'}, {'d','B'}, {'d','C'},
{'d','D'}, {'d','E'}, {'d','F'}, {'d','G'}, {'d','H'}, {'d','I'}, {'d','J'}, {'d','K'}, {'d','L'}, {'d','M'},
{'d','N'}, {'d','O'}, {'d','P'}, {'d','Q'}, {'d','R'}, {'d','S'}, {'d','T'}, {'d','U'}, {'d','V'}, {'d','W'},
{'d','X'}, {'d','Y'}, {'d','Z'}, {'b','P'}, {'b','Q'}, {'b','R'}, {'b','S'}, {'b','T'}
};
static const char start_stop[7] = { '1','1','1','1','4','1','1' }; /* 1st 6 start, all 7 stop */
/* SILVER includes the extra characters a, b, c and d to represent Code 93 specific
shift characters 1, 2, 3 and 4 respectively. These characters are never used by
`zint_code39()` and `excode39()` */
int i;
int h, weight, c, k, error_number = 0;
int values[125]; /* 123 + 2 (Checks) */
@@ -383,7 +380,7 @@ INTERNAL int zint_code93(struct zint_symbol *symbol, unsigned char source[], int
}
/* Start character */
memcpy(d, "111141", 6);
memcpy(d, start_stop, 6);
d += 6;
for (i = 0; i < h; i++, d += 6) {
@@ -391,7 +388,7 @@ INTERNAL int zint_code93(struct zint_symbol *symbol, unsigned char source[], int
}
/* Stop character */
memcpy(d, "1111411", 7);
memcpy(d, start_stop, 7);
d += 7;
z_expand(symbol, dest, (int) (d - dest));
+4 -10
View File
@@ -158,7 +158,8 @@ static int c128_cost(const unsigned char source[], const int length, const int i
const unsigned char ch = source[i];
const char *const latch_len = prior_cset == 0 ? c128_start_latch_len[start_idx] : c128_latch_len[prior_cset];
const int is_fnc1 = ch == '\x1D' && fncs[i];
const int can_c = is_fnc1 || (z_isdigit(ch) && z_isdigit(source[i + 1])); /* Assumes source NUL-terminated */
const int can_c = is_fnc1 ? i != 1 || !z_isalpha(source[0]) /* Don't use C if FNC1 in 2nd position after alpha */
: (z_isdigit(ch) && z_isdigit(source[i + 1])); /* Assumes source NUL-terminated */
const int manual_c_fail = !can_c && manuals[i] == C128_C0; /* C requested but not doable */
int min_cost = 999999; /* Max possible cost less than 2 * 256 */
int min_mode = 0;
@@ -247,14 +248,6 @@ static int c128_set_values(const unsigned char source[], const int length, const
*p_first_cset = modes[0][0];
}
/* Make sure FNC1 in 2nd position after single alpha does not switch modes before FNC1 */
if (length > 1 && !fncs[0] && fncs[1] && z_isalpha(source[0])) {
const int mode = modes[0][0];
if (mode == (mode & 0x0F) && mode != modes[1][mode]) {
modes[1][mode] = mode;
}
}
/* Output codewords into `values` */
for (i = 0; i < length; i++) {
const unsigned char ch = source[i];
@@ -309,6 +302,7 @@ static int c128_set_values(const unsigned char source[], const int length, const
/* Helper to write out symbol, calculating check digit */
static void c128_expand(struct zint_symbol *symbol, int values[C128_VALUES_MAX], int glyph_count) {
static const char stop[7] = { '2','3','3','1','1','1','2' };
char dest[640]; /* (102 + 1 (check digit)) * 6 + 7 (Stop) = 625 */
char *d = dest;
int total_sum;
@@ -329,7 +323,7 @@ static void c128_expand(struct zint_symbol *symbol, int values[C128_VALUES_MAX],
values[glyph_count++] = total_sum; /* For debug/test */
/* Stop character */
memcpy(d, "2331112", 7);
memcpy(d, stop, 7);
d += 7;
values[glyph_count++] = 106; /* For debug/test */
+4 -3
View File
@@ -1,7 +1,7 @@
/* dxfilmedge.c - Handles DX Film Edge symbology */
/*
libzint - the open source barcode library
Copyright (C) 2024-2025 Antoine Merino <antoine.merino.dev@gmail.com>
Copyright (C) 2024-2026 Antoine Merino <antoine.merino.dev@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -54,6 +54,7 @@
static int dx_parse_code(struct zint_symbol *symbol, const unsigned char *source, const int length,
char *binary_output, int *output_length, int *has_frame_info) {
static const char start_stop[6] = { '1','0','1','0','1','0' }; /* All 6 start, middle 4 stop */
int i;
int parity_bit = 0;
int dx_code_1 = -1, dx_code_2 = -1, frame_number = -1;
@@ -209,7 +210,7 @@ static int dx_parse_code(struct zint_symbol *symbol, const unsigned char *source
}
/* Build the binary output */
memcpy(binary_output, "101010", 6); /* Start pattern */
memcpy(binary_output, start_stop, 6); /* Start pattern */
bp = z_bin_append_posn(dx_code_1, 7, binary_output, 6);
binary_output[bp++] = '0'; /* Separator between DX part 1 and DX part 2 */
bp = z_bin_append_posn(dx_code_2, 4, binary_output, bp);
@@ -242,7 +243,7 @@ static int dx_parse_code(struct zint_symbol *symbol, const unsigned char *source
}
binary_output[bp++] = parity_bit ? '1' : '0';
memcpy(binary_output + bp, "0101", 4); /* Stop pattern */
memcpy(binary_output + bp, start_stop + 1, 4); /* Stop pattern */
bp += 4;
*output_length = bp;
+8 -3
View File
@@ -1671,9 +1671,14 @@ static void gs1se_gs_caret_sub(const unsigned char *src, const int length, unsig
/* Use GS1 Syntax Engine to verify */
static int gs1se_verify(struct zint_symbol *symbol, const unsigned char source[], const int length,
unsigned char reduced[], int *p_reduced_length) {
static const char linear_dummies[3][19] = {
{ '[','0','1',']','1','2','3','4','5','6','7','8','9','0','1','2','3','1','|' }, /* Normal */
{ '(','0','1',')','1','2','3','4','5','6','7','8','9','0','1','2','3','1','|' }, /* Parens */
{ '^','0','1','1','2','3','4','5','6','7','8','9','0','1','2','3','1','|','^' }, /* Raw/caret */
};
int i, j;
const int primary_len = z_is_composite(symbol->symbology) ? (int) strlen(symbol->primary) : 0;
const int gs1parens_mode = symbol->input_mode & GS1PARENS_MODE;
const int gs1parens_mode = !!(symbol->input_mode & GS1PARENS_MODE);
const int gs1raw_mode = !!(symbol->input_mode & GS1RAW_MODE);
const int gs1_caret = source[0] == '^';
const int is_digital_link = !primary_len && !gs1_caret && gs1_is_digital_link(source, length);
@@ -1742,7 +1747,7 @@ static int gs1se_verify(struct zint_symbol *symbol, const unsigned char source[]
} else {
/* Just use dummy "01" linear */
if (gs1_caret || gs1raw_mode) {
memcpy(local_source_buf, "^0112345678901231|^", 18 + gs1raw_mode);
memcpy(local_source_buf, linear_dummies[2], 18 + gs1raw_mode);
if (gs1_caret) {
memcpy(local_source_buf + 18, source, length + 1); /* Include terminating NUL */
} else {
@@ -1750,7 +1755,7 @@ static int gs1se_verify(struct zint_symbol *symbol, const unsigned char source[]
}
local_length += 18 + gs1raw_mode;
} else {
memcpy(local_source_buf, gs1parens_mode ? "(01)12345678901231|" : "[01]12345678901231|", 19);
memcpy(local_source_buf, linear_dummies[gs1parens_mode], 19);
memcpy(local_source_buf + 19, source, length + 1); /* Include terminating NUL */
local_length += 19;
}
+4 -5
View File
@@ -213,13 +213,11 @@ INTERNAL LIB_DECL_FUNC_SRC(zint_codablockf); /* Codablock */
INTERNAL LIB_DECL_FUNC_SRC(zint_nve18); /* NVE-18 */
INTERNAL LIB_DECL_FUNC_SRC(zint_japanpost); /* Japanese Post */
INTERNAL LIB_DECL_FUNC_SRC(zint_koreapost); /* Korea Post */
INTERNAL LIB_DECL_FUNC_SRC(zint_planet); /* PLANET */
INTERNAL LIB_DECL_FUNC_SEG(zint_micropdf417); /* Micro PDF417 */
INTERNAL LIB_DECL_FUNC_SRC(zint_usps_imail); /* Intelligent Mail (aka USPS OneCode) */
INTERNAL LIB_DECL_FUNC_SRC(zint_plessey); /* Plessey Code */
INTERNAL LIB_DECL_FUNC_SRC(zint_telepen_num); /* Telepen Numeric */
INTERNAL LIB_DECL_FUNC_SRC(zint_itf14); /* ITF-14 */
INTERNAL LIB_DECL_FUNC_SRC(zint_kix); /* TNT KIX Code */
INTERNAL LIB_DECL_FUNC_SEG(zint_aztec); /* Aztec Code */
INTERNAL LIB_DECL_FUNC_SRC(zint_daft); /* DAFT Code */
INTERNAL LIB_DECL_FUNC_SRC(zint_dpd); /* DPD Code */
@@ -531,9 +529,9 @@ static const barcode_src_func_t barcode_src_funcs[BARCODE_LAST + 1] = {
NULL, zint_auspost, zint_auspost, zint_auspost, zint_eanx, /*65-69*/
zint_rm4scc, NULL, zint_ean14, zint_vin, zint_codablockf, /*70-74*/
zint_nve18, zint_japanpost, zint_koreapost, NULL, zint_dbar_omn, /*75-79*/
zint_dbar_omn, zint_dbar_exp, zint_planet, NULL, NULL, /*80-84*/
zint_dbar_omn, zint_dbar_exp, zint_postnet, NULL, NULL, /*80-84*/
zint_usps_imail, zint_plessey, zint_telepen_num, NULL, zint_itf14, /*85-89*/
zint_kix, NULL, NULL, zint_daft, NULL, /*90-94*/
zint_rm4scc, NULL, NULL, zint_daft, NULL, /*90-94*/
NULL, zint_dpd, zint_microqr, NULL, NULL, /*95-99*/
NULL, NULL, NULL, NULL, NULL, /*100-104*/
NULL, NULL, NULL, NULL, NULL, /*105-109*/
@@ -1746,6 +1744,7 @@ int ZBarcode_BarcodeName(int symbol_id, char name[32]) {
"CHANNEL", "CODEONE", "GRIDMATRIX", "UPNQR", "ULTRA", /*140-144*/
"RMQR", "BC412", "DXFILMEDGE", "EAN8_CC", "EAN13_CC", /*145-149*/
};
static const char barcode_prefix[8] = { 'B','A','R','C','O','D','E','_' };
name[0] = '\0';
@@ -1754,7 +1753,7 @@ int ZBarcode_BarcodeName(int symbol_id, char name[32]) {
}
assert(symbol_id >= 0 && symbol_id < ARRAY_SIZE(names) && names[symbol_id][0]);
memcpy(name, "BARCODE_", 8);
memcpy(name, barcode_prefix, 8);
memcpy(name + 8, names[symbol_id], strlen(names[symbol_id]) + 1); /* Include terminating NUL */
return 0;
+3 -2
View File
@@ -514,6 +514,7 @@ INTERNAL int zint_datamatrix(struct zint_symbol *symbol, struct zint_seg segs[],
/* https://www.royalmailtechnical.com/rmt_docs/User_Guides_2021/Mailmark_Barcode_definition_document_20210215.pdf */
INTERNAL int zint_mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char spaces[9] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
static const char jgb_prefix[4] = { 'J','G','B',' ' };
unsigned char local_source[90 + 1];
char postcode[10];
int i;
@@ -531,11 +532,11 @@ INTERNAL int zint_mailmark_2d(struct zint_symbol *symbol, unsigned char source[]
/* Add prefix if missing */
memcpy(local_source, source, 4);
z_to_upper(local_source, 3);
if (memcmp(local_source, "JGB ", 4) != 0) {
if (memcmp(local_source, jgb_prefix, 4) != 0) {
if (length > 86) {
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 861, "Input length %d too long (maximum 86)", length);
}
memcpy(local_source, "JGB ", 4);
memcpy(local_source, jgb_prefix, 4);
memcpy(local_source + 4, source, length);
length += 4;
} else {
+11 -7
View File
@@ -54,10 +54,13 @@ static const char MSITable[10][8] = {
/* Not MSI/Plessey but the older Plessey standard */
INTERNAL int zint_plessey(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char grid[9] = { 1, 1, 1, 1, 0, 1, 0, 0, 1 };
static const char start[8] = { '3','1','3','1','1','3','3','1' };
static const char stop[9] = { '3','3','1','3','1','1','3','1','3' };
static const char checks[3] = { '1','3','1' }; /* Case 0 1st 2, case 1 2nd 2 */
int i;
unsigned char checkptr[67 * 4 + 8] = {0};
static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1};
char dest[570]; /* 8 + 67 * 8 + 2 * 8 + 9 + 1 = 570 */
char *d = dest;
unsigned int check_digits = 0;
@@ -74,7 +77,7 @@ INTERNAL int zint_plessey(struct zint_symbol *symbol, unsigned char source[], in
}
/* Start character */
memcpy(d, "31311331", 8);
memcpy(d, start, 8);
d += 8;
/* Data area */
@@ -101,11 +104,11 @@ INTERNAL int zint_plessey(struct zint_symbol *symbol, unsigned char source[], in
for (i = 0; i < 8; i++) {
switch (checkptr[length * 4 + i]) {
case 0:
memcpy(d, "13", 2);
memcpy(d, checks, 2);
d += 2;
break;
case 1:
memcpy(d, "31", 2);
memcpy(d, checks + 1, 2);
d += 2;
check_digits |= (1 << i);
break;
@@ -113,7 +116,7 @@ INTERNAL int zint_plessey(struct zint_symbol *symbol, unsigned char source[], in
}
/* Stop character */
memcpy(d, "331311313", 9);
memcpy(d, stop, 9);
d += 9;
z_expand(symbol, dest, (int) (d - dest));
@@ -327,6 +330,7 @@ static char *msi_plessey_mod1110(struct zint_symbol *symbol, const unsigned char
}
INTERNAL int zint_msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char stop_start[3] = { '1','2','1' }; /* All 3 stop, last 2 start */
int error_number = 0;
int i;
char dest[766]; /* 2 + 92 * 8 + 3 * 8 + 3 + 1 = 766 */
@@ -354,7 +358,7 @@ INTERNAL int zint_msi_plessey(struct zint_symbol *symbol, unsigned char source[]
}
/* Start character */
memcpy(d, "21", 2);
memcpy(d, stop_start + 1, 2);
d += 2;
switch (check_option) {
@@ -372,7 +376,7 @@ INTERNAL int zint_msi_plessey(struct zint_symbol *symbol, unsigned char source[]
}
/* Stop character */
memcpy(d, "121", 3);
memcpy(d, stop_start, 3);
d += 3;
z_expand(symbol, dest, (int) (d - dest));
+144 -274
View File
@@ -40,54 +40,6 @@ static const char KASUTSET[] = "1234567890-abcdefgh";
static const char CHKASUTSET[] = "0123456789-abcdefgh";
#define SHKASUTSET_F (IS_NUM_F | IS_MNS_F | IS_UPR_F) /* SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" */
/* PostNet number encoding table - In this table L is long as S is short */
static const char PNTable[10][5] = {
{'L','L','S','S','S'}, {'S','S','S','L','L'}, {'S','S','L','S','L'}, {'S','S','L','L','S'}, {'S','L','S','S','L'},
{'S','L','S','L','S'}, {'S','L','L','S','S'}, {'L','S','S','S','L'}, {'L','S','S','L','S'}, {'L','S','L','S','S'}
};
static const char PLTable[10][5] = {
{'S','S','L','L','L'}, {'L','L','L','S','S'}, {'L','L','S','L','S'}, {'L','L','S','S','L'}, {'L','S','L','L','S'},
{'L','S','L','S','L'}, {'L','S','S','L','L'}, {'S','L','L','L','S'}, {'S','L','L','S','L'}, {'S','L','S','L','L'}
};
static const char RoyalValues[36][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 },
{ 2, 5 }, { 2, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 0 }, { 4, 1 }, { 4, 2 },
{ 4, 3 }, { 4, 4 }, { 4, 5 }, { 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 5 }, { 5, 0 },
{ 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 0 }
};
/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
static const char RoyalTable[36][4] = {
{'3','3','0','0'}, {'3','2','1','0'}, {'3','2','0','1'}, {'2','3','1','0'}, {'2','3','0','1'}, {'2','2','1','1'},
{'3','1','2','0'}, {'3','0','3','0'}, {'3','0','2','1'}, {'2','1','3','0'}, {'2','1','2','1'}, {'2','0','3','1'},
{'3','1','0','2'}, {'3','0','1','2'}, {'3','0','0','3'}, {'2','1','1','2'}, {'2','1','0','3'}, {'2','0','1','3'},
{'1','3','2','0'}, {'1','2','3','0'}, {'1','2','2','1'}, {'0','3','3','0'}, {'0','3','2','1'}, {'0','2','3','1'},
{'1','3','0','2'}, {'1','2','1','2'}, {'1','2','0','3'}, {'0','3','1','2'}, {'0','3','0','3'}, {'0','2','1','3'},
{'1','1','2','2'}, {'1','0','3','2'}, {'1','0','2','3'}, {'0','1','3','2'}, {'0','1','2','3'}, {'0','0','3','3'}
};
static const char FlatTable[10][4] = {
{'0','5','0','4'}, { "18" }, {'0','1','1','7'}, {'0','2','1','6'}, {'0','3','1','5'},
{'0','4','1','4'}, {'0','5','1','3'}, {'0','6','1','2'}, {'0','7','1','1'}, {'0','8','1','0'}
};
static const char KoreaTable[10][10] = {
{'1','3','1','3','1','5','0','6','1','3'}, {'0','7','1','3','1','3','1','3','1','3'},
{'0','4','1','7','1','3','1','3','1','3'}, {'1','5','0','6','1','3','1','3','1','3'},
{'0','4','1','3','1','7','1','3','1','3'}, { "17171313" },
{'1','3','1','5','0','6','1','3','1','3'}, {'0','4','1','3','1','3','1','7','1','3'},
{ "17131713" }, { "13171713" }
};
static const char JapanTable[19][3] = {
{'1','1','4'}, {'1','3','2'}, {'3','1','2'}, {'1','2','3'}, {'1','4','1'},
{'3','2','1'}, {'2','1','3'}, {'2','3','1'}, {'4','1','1'}, {'1','4','4'},
{'4','1','4'}, {'3','2','4'}, {'3','4','2'}, {'2','3','4'}, {'4','3','2'},
{'2','4','3'}, {'4','2','3'}, {'4','4','1'}, {'1','1','1'}
};
/* Set height for POSTNET/PLANET/CEPNet codes, maintaining ratio */
static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
/* USPS Domestic Mail Manual (USPS DMM 300) Jan 8, 2006 (updated 2011) 708.4.2.5 POSTNET Barcode Dimensions and
@@ -133,14 +85,26 @@ static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
return error_number;
}
/* Handles the POSTNET system used for Zip codes in the US */
/* Also handles Brazilian CEPNet - more information CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) at
/* Handles the POSTNET system for delivering mail by ZIP codes in the US */
/* Also handles PLANET, used to tag outgoing/return mail & identify sender */
/* Also handles Brazilian CEPNet (ZIP-like) - more info CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) at
https://www.correios.com.br/enviar/correspondencia/arquivos/nacional/
guia-tecnico-cepnet-e-2d-triagem-enderecamento-27-04-2021.pdf/view
*/
static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[], char *d, const int length) {
INTERNAL int zint_postnet(struct zint_symbol *symbol, unsigned char source[], int length) {
/* For POSTNET/CEPNet 1 is ascender and 0 is tracker, vice versa for PLANET */
static const char POSTNET_PLANET[10][5] = {
{ 1,1,0,0,0 }, { 0,0,0,1,1 }, { 0,0,1,0,1 }, { 0,0,1,1,0 }, { 0,1,0,0,1 },
{ 0,1,0,1,0 }, { 0,1,1,0,0 }, { 1,0,0,0,1 }, { 1,0,0,1,0 }, { 1,0,1,0,0 }
};
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
char dest[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
char *d = dest;
unsigned int loopey, h;
int writer;
int error_number = 0, warn_number;
int i, sum, check_digit;
int error_number = 0;
const int ascender = symbol->symbology != BARCODE_PLANET; /* PLANET uses 0 for ascender, 1 for tracker */
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
if (length > 38) {
@@ -148,11 +112,19 @@ static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[],
}
if (symbol->symbology == BARCODE_CEPNET) {
/* 5 (area) + 3 (+location within area) */
if (length != 8) {
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 780,
"Input length %d wrong (should be 8 digits)", length);
}
} else if (symbol->symbology == BARCODE_PLANET) {
/* 2 (delivery/return) + 9 or 11 (identification) */
if (length != 11 && length != 13) {
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 478,
"Input length %d is not standard (should be 11 or 13 digits)", length);
}
} else {
/* 5 ZIP (area), 9 ZIP+4 (+location within area), 11 ZIP+6 (+delivery point barcode) */
if (length != 5 && length != 9 && length != 11) {
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 479,
"Input length %d is not standard (should be 5, 9 or 11 digits)", length);
@@ -162,137 +134,53 @@ static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[],
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 481,
"Invalid character at position %d in input (digits only)", i);
}
sum = 0;
/* Start character */
*d++ = 'L';
*d++ = ascender;
sum = 0;
for (i = 0; i < length; i++, d += 5) {
const int val = source[i] - '0';
memcpy(d, PNTable[val], 5);
memcpy(d, POSTNET_PLANET[val], 5);
sum += val;
}
check_digit = (10 - (sum % 10)) % 10;
memcpy(d, PNTable[check_digit], 5);
memcpy(d, POSTNET_PLANET[check_digit], 5);
d += 5;
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
/* Stop character */
memcpy(d, "L", 2); /* Include terminating NUL */
*d++ = ascender;
if (content_segs && z_ct_cpy_cat(symbol, source, length, (char) z_itoc(check_digit), NULL /*cat*/, 0)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
}
return error_number;
}
/* Puts POSTNET barcodes into the pattern matrix */
INTERNAL int zint_postnet(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
unsigned int loopey, h;
int writer;
int error_number, warn_number;
error_number = postnet_enc(symbol, source, height_pattern, length);
if (error_number >= ZINT_ERROR) {
return error_number;
}
writer = 0;
h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == 'L') {
h = d - dest;
for (loopey = 0, writer = 0; loopey < h; loopey++, writer += 2) {
if (dest[loopey] == ascender) {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
writer += 2;
z_set_module(symbol, 1, writer); /* Tracker */
}
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
symbol->rows = 2;
symbol->width = writer - 1;
return error_number ? error_number : warn_number;
}
/* Handles the PLANET system used for item tracking in the US */
static int planet_enc(struct zint_symbol *symbol, const unsigned char source[], char *d, const int length) {
int i, sum, check_digit;
int error_number = 0;
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
if (length > 38) {
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 482, "Input length %d too long (maximum 38)", length);
}
if (length != 11 && length != 13) {
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 478,
"Input length %d is not standard (should be 11 or 13 digits)", length);
}
if ((i = z_not_sane(NEON_F, source, length))) {
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 483,
"Invalid character at position %d in input (digits only)", i);
}
sum = 0;
/* Start character */
*d++ = 'L';
for (i = 0; i < length; i++, d += 5) {
const int val = source[i] - '0';
memcpy(d, PLTable[val], 5);
sum += val;
}
check_digit = (10 - (sum % 10)) % 10;
memcpy(d, PLTable[check_digit], 5);
d += 5;
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
/* Stop character */
memcpy(d, "L", 2); /* Include terminating NUL */
if (content_segs && z_ct_cpy_cat(symbol, source, length, (char) z_itoc(check_digit), NULL /*cat*/, 0)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
}
return error_number;
}
/* Puts PLANET barcodes into the pattern matrix */
INTERNAL int zint_planet(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
unsigned int loopey, h;
int writer;
int error_number, warn_number;
error_number = planet_enc(symbol, source, height_pattern, length);
if (error_number >= ZINT_ERROR) {
return error_number;
}
writer = 0;
h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == 'L') {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
writer += 2;
}
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
symbol->rows = 2;
symbol->width = writer - 1;
return error_number ? error_number : warn_number;
}
/* Korean Postal Authority */
INTERNAL int zint_koreapost(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char KoreaTable[10][10] = {
{'1','3','1','3','1','5','0','6','1','3'}, {'0','7','1','3','1','3','1','3','1','3'},
{'0','4','1','7','1','3','1','3','1','3'}, {'1','5','0','6','1','3','1','3','1','3'},
{'0','4','1','3','1','7','1','3','1','3'}, { "17171313" },
{'1','3','1','5','0','6','1','3','1','3'}, {'0','4','1','3','1','3','1','7','1','3'},
{ "17131713" }, { "13171713" }
};
int total, i, check, zeroes, error_number = 0;
unsigned char local_source[8];
char dest[80];
@@ -346,6 +234,11 @@ INTERNAL int zint_koreapost(struct zint_symbol *symbol, unsigned char source[],
/* The simplest barcode symbology ever! Supported by MS Word, so here it is!
glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
INTERNAL int zint_fim(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char a[9] = { '1','1','1','5','1','5','1','1','1' };
static const char b[11] = { '1','3','1','1','1','3','1','1','1','3','1' };
static const char c[11] = { '1','1','1','3','1','3','1','3','1','1','1' };
static const char d[13] = { '1','1','1','1','1','3','1','3','1','1','1','1','1' };
static const char e[7] = { '1','3','1','7','1','3','1' };
int error_number = 0;
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
@@ -357,19 +250,19 @@ INTERNAL int zint_fim(struct zint_symbol *symbol, unsigned char source[], int le
switch ((char) source[0]) {
case 'A':
z_expand(symbol, "111515111", 9);
z_expand(symbol, a, 9);
break;
case 'B':
z_expand(symbol, "13111311131", 11);
z_expand(symbol, b, 11);
break;
case 'C':
z_expand(symbol, "11131313111", 11);
z_expand(symbol, c, 11);
break;
case 'D':
z_expand(symbol, "1111131311111", 13);
z_expand(symbol, d, 13);
break;
case 'E':
z_expand(symbol, "1317131", 7);
z_expand(symbol, e, 7);
break;
default:
return z_errtxt(ZINT_ERROR_INVALID_DATA, symbol, 487,
@@ -428,22 +321,57 @@ INTERNAL int zint_daft_set_height(struct zint_symbol *symbol, const float min_he
return error_number;
}
/* Handles the 4 State barcodes used in the UK by Royal Mail. Returns check_character */
static int rm4scc_enc(struct zint_symbol *symbol, const int *posns, char *d, const int length) {
/* Helper to expand 4-states into 3 rows, where 0 = Full, 1 = Ascender, 2 = Descender, 3 Tracker (always) */
static void post_4state(struct zint_symbol *symbol, char *dest, const int length) {
int loopey, writer;
for (loopey = 0, writer = 0; loopey < length; loopey++, writer += 2) {
if (dest[loopey] == 1 || dest[loopey] == 0) { /* Ascender/full */
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer); /* Tracker */
if (dest[loopey] == 2 || dest[loopey] == 0) { /* Descender/full */
z_set_module(symbol, 2, writer);
}
}
symbol->rows = 3;
symbol->width = writer - 1;
}
/* Used by Royal Mail 4-state (& KIX) - 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
static const char RM4KIX[36][4] = {
{ 3,3,0,0 }, { 3,2,1,0 }, { 3,2,0,1 }, { 2,3,1,0 }, { 2,3,0,1 }, { 2,2,1,1 },
{ 3,1,2,0 }, { 3,0,3,0 }, { 3,0,2,1 }, { 2,1,3,0 }, { 2,1,2,1 }, { 2,0,3,1 },
{ 3,1,0,2 }, { 3,0,1,2 }, { 3,0,0,3 }, { 2,1,1,2 }, { 2,1,0,3 }, { 2,0,1,3 },
{ 1,3,2,0 }, { 1,2,3,0 }, { 1,2,2,1 }, { 0,3,3,0 }, { 0,3,2,1 }, { 0,2,3,1 },
{ 1,3,0,2 }, { 1,2,1,2 }, { 1,2,0,3 }, { 0,3,1,2 }, { 0,3,0,3 }, { 0,2,1,3 },
{ 1,1,2,2 }, { 1,0,3,2 }, { 1,0,2,3 }, { 0,1,3,2 }, { 0,1,2,3 }, { 0,0,3,3 }
};
/* Handles the 4-state barcodes used in the UK by Royal Mail. Returns check_character */
static int rm4scc_enc(struct zint_symbol *symbol, const int *const posns, char *const dest, const int length,
int *p_dest_len) {
static const char CheckCharTopBottom[36][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 },
{ 2, 5 }, { 2, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 0 }, { 4, 1 }, { 4, 2 },
{ 4, 3 }, { 4, 4 }, { 4, 5 }, { 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 5 }, { 5, 0 },
{ 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 0 }
};
int i;
int top, bottom, row, column, check_digit;
char *d = dest;
top = 0;
bottom = 0;
/* Start character */
*d++ = '1';
*d++ = 1; /* Ascender */
for (i = 0; i < length; i++, d += 4) {
const int p = posns[i];
memcpy(d, RoyalTable[p], 4);
top += RoyalValues[p][0];
bottom += RoyalValues[p][1];
memcpy(d, RM4KIX[p], 4);
top += CheckCharTopBottom[p][0];
bottom += CheckCharTopBottom[p][1];
}
/* Calculate the check digit */
@@ -456,51 +384,60 @@ static int rm4scc_enc(struct zint_symbol *symbol, const int *posns, char *d, con
column = 5;
}
check_digit = (6 * row) + column;
memcpy(d, RoyalTable[check_digit], 4);
memcpy(d, RM4KIX[check_digit], 4);
d += 4;
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
/* Stop character */
memcpy(d, "0", 2); /* Include terminating NUL */
*d++ = 0; /* Full */
*p_dest_len = d - dest;
return KRSET[check_digit];
}
/* Puts RM4SCC into the data matrix */
/* Royal Mail 4-State Customer Code (RM4SCC) */
/* Also handles Dutch Post TNT KIX symbols
The same as RM4SCC but without check digit or stop/start chars
Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int length) {
int i;
char height_pattern[210];
char dest[210];
int posns[50];
int loopey, h;
int writer;
int h;
char check_digit;
int error_number = 0;
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
if (symbol->symbology == BARCODE_KIX) {
if (length > 18) {
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 490, "Input length %d too long (maximum 18)", length);
}
} else {
if (length > 50) {
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 488, "Input length %d too long (maximum 50)", length);
}
}
z_to_upper(source, length);
if ((i = z_not_sane_lookup(KRSET, 36, source, length, posns))) {
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 489,
"Invalid character at position %d in input (alphanumerics only)", i);
}
check_digit = rm4scc_enc(symbol, posns, height_pattern, length);
/* Encode data */
if (symbol->symbology == BARCODE_KIX) {
char *d = dest;
for (i = 0; i < length; i++, d += 4) {
memcpy(d, RM4KIX[posns[i]], 4);
}
h = (int) (d - dest);
check_digit = '\xFF'; /* None */
} else {
check_digit = rm4scc_enc(symbol, posns, dest, length, &h);
}
writer = 0;
h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == '1' || height_pattern[loopey] == '0') {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
if (height_pattern[loopey] == '2' || height_pattern[loopey] == '0') {
z_set_module(symbol, 2, writer);
}
writer += 2;
}
post_4state(symbol, dest, h);
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* Royal Mail Know How User's Manual Appendix C: using CBC
@@ -509,6 +446,7 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
Bar pitch and min/maxes same as Mailmark, so using recommendations from
Royal Mail Mailmark Barcode Definition Document (15 Sept 2015) Section 3.5.1
*/
/* KIX same */
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
@@ -520,8 +458,6 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
symbol->row_height[1] = 2.0f;
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
}
symbol->rows = 3;
symbol->width = writer - 1;
if (content_segs && z_ct_cpy_cat(symbol, source, length, check_digit, NULL /*cat*/, 0)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
@@ -530,67 +466,6 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
return error_number;
}
/* Handles Dutch Post TNT KIX symbols
The same as RM4SCC but without check digit or stop/start chars
Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
INTERNAL int zint_kix(struct zint_symbol *symbol, unsigned char source[], int length) {
char height_pattern[75];
char *d = height_pattern;
int posns[18];
int loopey;
int writer, i, h;
int error_number = 0;
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
if (length > 18) {
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 490, "Input length %d too long (maximum 18)", length);
}
z_to_upper(source, length);
if ((i = z_not_sane_lookup(KRSET, 36, source, length, posns))) {
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 491,
"Invalid character at position %d in input (alphanumerics only)", i);
}
/* Encode data */
for (i = 0; i < length; i++, d += 4) {
memcpy(d, RoyalTable[posns[i]], 4);
}
writer = 0;
h = (int) (d - height_pattern);
for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == '1' || height_pattern[loopey] == '0') {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
if (height_pattern[loopey] == '2' || height_pattern[loopey] == '0') {
z_set_module(symbol, 2, writer);
}
writer += 2;
}
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* Dimensions same as RM4SCC */
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
symbol->row_height[1] = 2.16496062f; /* (1.3 * 42.3) / 25.4 */
/* Note using max X for minimum and min X for maximum */
error_number = zint_daft_set_height(symbol, min_height, max_height);
} else {
symbol->row_height[0] = 3.0f;
symbol->row_height[1] = 2.0f;
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
}
symbol->rows = 3;
symbol->width = writer - 1;
if (content_segs && z_ct_cpy(symbol, source, length)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy()` only fails with OOM */
}
return error_number;
}
/* Handles DAFT Code symbols */
INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int length) {
@@ -610,17 +485,17 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
"Invalid character at position %d in input (\"D\", \"A\", \"F\" and \"T\" only)", i);
}
writer = 0;
for (loopey = 0; loopey < length; loopey++) {
if (posns[loopey] == 1 || posns[loopey] == 0) {
for (loopey = 0, writer = 0; loopey < length; loopey++, writer += 2) {
if (posns[loopey] == 1 || posns[loopey] == 0) { /* Ascender/full */
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
if (posns[loopey] == 2 || posns[loopey] == 0) {
z_set_module(symbol, 1, writer); /* Tracker */
if (posns[loopey] == 2 || posns[loopey] == 0) { /* Descender/full */
z_set_module(symbol, 2, writer);
}
writer += 2;
}
symbol->rows = 3;
symbol->width = writer - 1;
/* Allow ratio of tracker to be specified in thousandths */
if (symbol->option_2 >= 50 && symbol->option_2 <= 900) {
@@ -637,8 +512,6 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
/* DAFT generic barcode so no dimensions/height specification */
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
symbol->rows = 3;
symbol->width = writer - 1;
if (content_segs && z_ct_cpy(symbol, source, length)) {
return ZINT_ERROR_MEMORY; /* `z_ct_cpy()` only fails with OOM */
@@ -649,6 +522,10 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
/* Flattermarken - Not really a barcode symbology! */
INTERNAL int zint_flat(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char FlatTable[10][4] = {
{'0','5','0','4'}, { "18" }, {'0','1','1','7'}, {'0','2','1','6'}, {'0','3','1','5'},
{'0','4','1','4'}, {'0','5','1','3'}, {'0','6','1','2'}, {'0','7','1','1'}, {'0','8','1','0'}
};
int i, error_number = 0;
char dest[512]; /* 128 * 4 = 512 */
char *d = dest;
@@ -681,10 +558,17 @@ INTERNAL int zint_flat(struct zint_symbol *symbol, unsigned char source[], int l
/* Japanese Postal Code (Kasutama Barcode) */
INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[], int length) {
int error_number = 0, h;
char pattern[69];
char *d = pattern;
int writer, loopey, inter_posn, i, sum, check;
static const char JapanTable[19][3] = {
{ 0,0,3 }, { 0,2,1 }, { 2,0,1 }, { 0,1,2 }, { 0,3,0 },
{ 2,1,0 }, { 1,0,2 }, { 1,2,0 }, { 3,0,0 }, { 0,3,3 },
{ 3,0,3 }, { 2,1,3 }, { 2,3,1 }, { 1,2,3 }, { 3,2,1 },
{ 1,3,2 }, { 3,1,2 }, { 3,3,0 }, { 0,0,0 }
};
static const char start_stop[3] = { 0,2,0 }; /* 1st 2 chars start, last 2 chars stop */
int error_number = 0;
char dest[69];
char *d = dest;
int inter_posn, i, sum, check;
char check_char;
unsigned char inter[20 + 1];
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
@@ -729,7 +613,7 @@ INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[],
"Input too long, requires too many symbol characters (maximum 20)");
}
memcpy(d, "13", 2); /* Start */
memcpy(d, start_stop, 2); /* Start */
d += 2;
sum = 0;
@@ -755,25 +639,11 @@ INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[],
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check: %d, char: %c\n", check, check_char);
memcpy(d, "31", 2); /* Stop */
memcpy(d, start_stop + 1, 2); /* Stop */
d += 2;
/* Resolve pattern to 4-state symbols */
writer = 0;
h = (int) (d - pattern);
for (loopey = 0; loopey < h; loopey++) {
if (pattern[loopey] == '2' || pattern[loopey] == '1') {
z_set_module(symbol, 0, writer);
}
z_set_module(symbol, 1, writer);
if (pattern[loopey] == '3' || pattern[loopey] == '1') {
z_set_module(symbol, 2, writer);
}
writer += 2;
}
symbol->rows = 3;
symbol->width = writer - 1;
post_4state(symbol, dest, (int) (d - dest));
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* Japan Post Zip/Barcode Manual pp.11-12 https://www.post.japanpost.jp/zipcode/zipmanual/p11.html
+11 -7
View File
@@ -1,7 +1,7 @@
/* svg.c - Scalable Vector Graphics */
/*
libzint - the open source barcode library
Copyright (C) 2009-2025 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2009-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -58,33 +58,37 @@ static void svg_pick_colour(const int colour, char colour_code[7]) {
/* Convert text to use HTML entity codes */
static void svg_make_html_friendly(const unsigned char *string, char *html_version) {
static const char gt[4] = { '&','g','t',';' };
static const char lt[4] = { '&','l','t',';' };
static const char amp[5] = { '&','a','m','p',';' };
static const char quot[6] = { '&','q','u','o','t',';' };
static const char apos[6] = { '&','a','p','o','s',';' };
/* `NOLINT` required due to disconnect between `symbol->text` and vector `string`s which are always <= */
/* NOLINTBEGIN(clang-analyzer-security.ArrayBound) clang-tidy-21 false positive */
for (; *string; string++) {
switch (*string) {
case '>':
memcpy(html_version, "&gt;", 4);
memcpy(html_version, gt, 4);
html_version += 4;
break;
case '<':
memcpy(html_version, "&lt;", 4);
memcpy(html_version, lt, 4);
html_version += 4;
break;
case '&':
memcpy(html_version, "&amp;", 5);
memcpy(html_version, amp, 5);
html_version += 5;
break;
case '"':
memcpy(html_version, "&quot;", 6);
memcpy(html_version, quot, 6);
html_version += 6;
break;
case '\'':
memcpy(html_version, "&apos;", 6);
memcpy(html_version, apos, 6);
html_version += 6;
break;
+94 -46
View File
@@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2020-2025 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2020-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -195,25 +195,29 @@ static void test_input(const testCtx *const p_ctx) {
static const struct item data[] = {
/* 0*/ { BARCODE_AUSPOST, "12345678", 0, 3, 73, "" },
/* 1*/ { BARCODE_AUSPOST, "1234567A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 405: Invalid character at position 8 in DPID (first 8 characters) (digits only)" },
/* 2*/ { BARCODE_AUSPOST, "12345678ABcd#", 0, 3, 103, "" },
/* 3*/ { BARCODE_AUSPOST, "12345678ABcd!", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 404: Invalid character at position 13 in input (alphanumerics, space and \"#\" only)" },
/* 4*/ { BARCODE_AUSPOST, "12345678ABcd#", 0, 3, 103, "" },
/* 5*/ { BARCODE_AUSPOST, "1234567890123456", 0, 3, 103, "" },
/* 6*/ { BARCODE_AUSPOST, "123456789012345A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 402: Invalid character at position 16 in input (digits only for FCC 59 length 16)" },
/* 7*/ { BARCODE_AUSPOST, "12345678ABCDefgh #", 0, 3, 133, "" }, /* Length 18 */
/* 8*/ { BARCODE_AUSPOST, "12345678901234567890123", 0, 3, 133, "" },
/* 9*/ { BARCODE_AUSPOST, "1234567890123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 406: Invalid character at position 23 in input (digits only for FCC 62 length 23)" },
/* 10*/ { BARCODE_AUSPOST, "1234567", ZINT_ERROR_TOO_LONG, -1, -1, "Error 401: Input length 7 wrong (8, 13, 16, 18 or 23 characters required)" }, /* No leading zeroes added */
/* 11*/ { BARCODE_AUSREPLY, "12345678", 0, 3, 73, "" },
/* 12*/ { BARCODE_AUSREPLY, "1234567", 0, 3, 73, "" }, /* Leading zeroes added */
/* 13*/ { BARCODE_AUSREPLY, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
/* 14*/ { BARCODE_AUSROUTE, "123456", 0, 3, 73, "" },
/* 15*/ { BARCODE_AUSROUTE, "12345", 0, 3, 73, "" },
/* 16*/ { BARCODE_AUSROUTE, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
/* 17*/ { BARCODE_AUSREDIRECT, "1234", 0, 3, 73, "" },
/* 18*/ { BARCODE_AUSREDIRECT, "123", 0, 3, 73, "" },
/* 19*/ { BARCODE_AUSREDIRECT, "0", 0, 3, 73, "" },
/* 20*/ { BARCODE_AUSREDIRECT, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
/* 2*/ { BARCODE_AUSPOST, "0000000A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 405: Invalid character at position 8 in DPID (first 8 characters) (digits only)" },
/* 3*/ { BARCODE_AUSPOST, "12345678ABcd#", 0, 3, 103, "" },
/* 4*/ { BARCODE_AUSPOST, "12345678ABcd!", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 404: Invalid character at position 13 in input (alphanumerics, space and \"#\" only)" },
/* 5*/ { BARCODE_AUSPOST, "00000000ABcd!", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 404: Invalid character at position 13 in input (alphanumerics, space and \"#\" only)" },
/* 6*/ { BARCODE_AUSPOST, "12345678ABcd#", 0, 3, 103, "" },
/* 7*/ { BARCODE_AUSPOST, "1234567890123456", 0, 3, 103, "" },
/* 8*/ { BARCODE_AUSPOST, "123456789012345A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 402: Invalid character at position 16 in input (digits only for FCC 59 length 16)" },
/* 9*/ { BARCODE_AUSPOST, "000000009012345A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 402: Invalid character at position 16 in input (digits only for FCC 59 length 16)" },
/* 10*/ { BARCODE_AUSPOST, "12345678ABCDefgh #", 0, 3, 133, "" }, /* Length 18 */
/* 11*/ { BARCODE_AUSPOST, "12345678901234567890123", 0, 3, 133, "" },
/* 12*/ { BARCODE_AUSPOST, "1234567890123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 406: Invalid character at position 23 in input (digits only for FCC 62 length 23)" },
/* 13*/ { BARCODE_AUSPOST, "0000000090123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 406: Invalid character at position 23 in input (digits only for FCC 62 length 23)" },
/* 14*/ { BARCODE_AUSPOST, "1234567", ZINT_ERROR_TOO_LONG, -1, -1, "Error 401: Input length 7 wrong (8, 13, 16, 18 or 23 characters required)" }, /* No leading zeroes added */
/* 15*/ { BARCODE_AUSREPLY, "12345678", 0, 3, 73, "" },
/* 16*/ { BARCODE_AUSREPLY, "1234567", 0, 3, 73, "" }, /* Leading zeroes added */
/* 17*/ { BARCODE_AUSREPLY, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
/* 18*/ { BARCODE_AUSROUTE, "123456", 0, 3, 73, "" },
/* 19*/ { BARCODE_AUSROUTE, "12345", 0, 3, 73, "" },
/* 20*/ { BARCODE_AUSROUTE, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
/* 21*/ { BARCODE_AUSREDIRECT, "1234", 0, 3, 73, "" },
/* 22*/ { BARCODE_AUSREDIRECT, "123", 0, 3, 73, "" },
/* 23*/ { BARCODE_AUSREDIRECT, "0", 0, 3, 73, "" },
/* 24*/ { BARCODE_AUSREDIRECT, "123456789", ZINT_ERROR_TOO_LONG, -1, -1, "Error 403: Input length 9 too long (maximum 8)" },
};
const int data_size = ARRAY_SIZE(data);
int i, length, ret;
@@ -277,81 +281,108 @@ static void test_encode(const testCtx *const p_ctx) {
int expected_rows;
int expected_width;
int bwipp_cmp;
const char *comment;
const char *expected;
};
/* s/\v(\/\*)[ 0-9]*(\*\/)/\=printf("%s%3d%s", submatch(1), (@z+setreg('z',@z+1)), submatch(2))/ | let @z=0: */
static const struct item data[] = {
/* 0*/ { BARCODE_AUSPOST, "96184209", 0, 3, 73, "AusPost Tech Specs Diagram 1; verified manually against TEC-IT",
/* 0*/ { BARCODE_AUSPOST, "96184209", 0, 3, 73, 1, "AusPost Tech Specs Diagram 1; verified manually against TEC-IT",
"1000101010100010001010100000101010001010001000001010000010001000001000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000100010000010101010001010000010101010001000101010001000100010000010000"
},
/* 1*/ { BARCODE_AUSPOST, "39549554", 0, 3, 73, "AusPost Guide Figure 3, same; verified manually against TEC-IT",
/* 1*/ { BARCODE_AUSPOST, "39549554", 0, 3, 73, 1, "AusPost Guide Figure 3, same; verified manually against TEC-IT",
"1000101010101010001010001010001010001000101000001000101010001010000000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000100010000010001000100000001000100010000000000010001000000000001010000"
},
/* 2*/ { BARCODE_AUSPOST, "56439111ABA 9", 0, 3, 103, "AusPost Guide Figure 4, same; verified manually against TEC-IT",
/* 2*/ { BARCODE_AUSPOST, "56439111ABA 9", 0, 3, 103, 1, "AusPost Guide Figure 4, same; verified manually against TEC-IT",
"1000100000101000001010101010001010101010101010101010101010101010100000000000001010100010101010000010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000001000100010101000000010001010001000100010101010100010101010100000101000000010001000101010000000000"
},
/* 3*/ { BARCODE_AUSPOST, "3221132412345678", 0, 3, 103, "59 Custom 2 N encoding",
/* 3*/ { BARCODE_AUSPOST, "3221132412345678", 0, 3, 103, 1, "59 Custom 2 N encoding",
"1000100000101010100010001010101010101000101010101000101010101000001000100000101000000000001000000000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000001000100010101010101000100000101010000010001010001000000010101010001010000010001010101000100000000"
},
/* 4*/ { BARCODE_AUSPOST, "32211324Ab #2", 0, 3, 103, "59 Custom 2 C encoding",
/* 4*/ { BARCODE_AUSPOST, "32211324Ab #2", 0, 3, 103, 1, "59 Custom 2 C encoding",
"1000100000101010100010001010101010101000101010101010001010100010100000101000100000000010100000100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000001000100010101010101000100000101010000010101010001010100010000000100000001000101010000010000000000"
},
/* 5*/ { BARCODE_AUSPOST, "32211324123456789012345", 0, 3, 133, "62 Custom 3 N encoding",
/* 5*/ { BARCODE_AUSPOST, "32211324123456789012345", 0, 3, 133, 1, "62 Custom 3 N encoding",
"1000001010001010100010001010101010101000101010101000101010101000001000100000001010101010100010101010100000100000100010101010100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010100010101010101000100000101010000010001010001000000010101010001010001010101000101000100000001000001010000010001010100010000"
},
/* 6*/ { BARCODE_AUSPOST, "32211324aBCd#F hIz", 0, 3, 133, "62 Custom 3 C encoding",
/* 6*/ { BARCODE_AUSPOST, "32211324aBCd#F hIz", 0, 3, 133, 1, "62 Custom 3 C encoding",
"1000001010001010100010001010101010101000101010000010101010100010000010100010100010100010000010000000000000100010100010101010000000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010100010101010101000100000101010000010100010100010101010001010000010001010100000100010101000000000101000001010100000000010000"
},
/* 7*/ { BARCODE_AUSPOST, "12345678DEGHJKLMNO", 0, 3, 133, "62 Custom 3 C encoding GDSET 1st part",
/* 7*/ { BARCODE_AUSPOST, "12345678DEGHJKLMNO", 0, 3, 133, 1, "62 Custom 3 C encoding GDSET 1st part",
"1000001010001010100010101010100000100010000010101010101010001010001010101010101010100010101010101010100000001010000010000000000010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101000101000100000001010101000101010001010000010101010100000101000100000101000001000000000001000001010000010001010001010000"
},
/* 8*/ { BARCODE_AUSPOST, "23456789PQRSTUVWXY", 0, 3, 133, "62 Custom 3 C encoding GDSET 2nd part",
/* 8*/ { BARCODE_AUSPOST, "23456789PQRSTUVWXY", 0, 3, 133, 1, "62 Custom 3 C encoding GDSET 2nd part",
"1000001010001000101010101000001000100000001010001010001010000000101000101000100000101000101000100000001000101000101010101000101010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010001000000010101010001010001000101000100000101010101010100010101010001010000010001010101000000010001000001010101000000"
},
/* 9*/ { BARCODE_AUSPOST, "34567890Zcefgijklm", 0, 3, 133, "62 Custom 3 C encoding GDSET 3rd part",
/* 9*/ { BARCODE_AUSPOST, "34567890Zcefgijklm", 0, 3, 133, 1, "62 Custom 3 C encoding GDSET 3rd part",
"1000001010001010101010000010001000000010101000001010001010000010100010100010001010001010000010000000100000101000100000001010001010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010100010000000101010100010100010101010100010000010000000100000000000001000000000001000000010100000101000000010101010100010000"
},
/* 10*/ { BARCODE_AUSPOST, "12345678lnopqrstuv", 0, 3, 133, "62 Custom 3 C encoding GDSET 4th part",
/* 10*/ { BARCODE_AUSPOST, "12345678lnopqrstuv", 0, 3, 133, 1, "62 Custom 3 C encoding GDSET 4th part",
"1000001010001010100010101010100000100010000010000000100000000000001000001000000000000000100000100000000000001010001010101000000010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101000101000100000001010101000101000000010000010100010001010000010001010000000100000000000100000100000001010001000100000000"
},
/* 11*/ { BARCODE_AUSPOST, "09876543wxy# ", 0, 3, 103, "59 Custom 2 C encoding GDSET 5th part",
/* 11*/ { BARCODE_AUSPOST, "09876543wxy# ", 0, 3, 103, 1, "59 Custom 2 C encoding GDSET 5th part",
"1000100000101010001000000010001010001010101000001000001000000010100010100000100010000000000010100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000001000101010001010101000101000100000001000001000000000001010000010100000001010001000001000100000000"
},
/* 12*/ { BARCODE_AUSREPLY, "12345678", 0, 3, 73, "Verified manually against tec-it",
/* 12*/ { BARCODE_AUSPOST, "00000000", 0, 3, 73, 0, "Null (DPID all-zeros) length 8; BWIPP: not supported yet",
"1000101010101010101010101010101010101010101000001000001000001000101000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010101010101010101010101010101000101010100000001000001000000"
},
/* 13*/ { BARCODE_AUSPOST, "00000000ABC 9", 0, 3, 103, 0, "Null length 13; BWIPP: not supported yet",
"1000101010101010101010101010101010101010101010101010101010100010100000000000100000001000101000000000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010101010101010101010101010101010101010100010101010100000101000101010001010001000000000000"
},
/* 14*/ { BARCODE_AUSPOST, "0000000012345678", 0, 3, 103, 0, "Null length 16; BWIPP: not supported yet",
"1000101010101010101010101010101010101010101010101000101010101000001000100000001000101000001010100000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010101010101010101010101010101010001010001000000010101010001010001010101010101010101010000"
},
/* 15*/ { BARCODE_AUSPOST, "00000000aBCd#F hIz", 0, 3, 133, 0, "Null length 18; BWIPP: not supported yet",
"1000101010101010101010101010101010101010101010000010101010100010000010100010100010100010000010000000000000001010100000000000000000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010101010101010101010101010101010100010100010101010001010000010001010100000100010101000000000001000001000000000000000000"
},
/* 16*/ { BARCODE_AUSPOST, "00000000123456789012345", 0, 3, 133, 0, "Null length 23; BWIPP: not supported yet",
"1000101010101010101010101010101010101010101010101000101010101000001000100000001010101010100010101010100000001000100000000000100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010101010101010101010101010101010101010001010001000000010101010001010001010101000101000100000001000101010000000101010100000000"
},
/* 17*/ { BARCODE_AUSREPLY, "12345678", 0, 3, 73, 1, "Verified manually against TEC-IT",
"1000101010001010100010101010100000100010000000001000001000000000100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000000000101000101000100000001010101000101000000000100010101000101000000"
},
/* 13*/ { BARCODE_AUSROUTE, "34567890", 0, 3, 73, "Verified manually against tec-it",
/* 18*/ { BARCODE_AUSROUTE, "34567890", 0, 3, 73, 1, "Verified manually against TEC-IT",
"1000000000101010101010000010001000000010101000100010101010000000101000100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000101010000010000000101010100010100010101000100010101010001010001000000"
},
/* 14*/ { BARCODE_AUSREDIRECT, "98765432", 0, 3, 73, "Verified manually against tec-it",
/* 19*/ { BARCODE_AUSREDIRECT, "98765432", 0, 3, 73, 1, "Verified manually against TEC-IT",
"1000001010000010000000100010100010101010100000101010101000100010100010100"
"1010101010101010101010101010101010101010101010101010101010101010101010101"
"0000001010100010101010001010001000000010101000000000001010101000001010000"
@@ -376,34 +407,51 @@ static void test_encode(const testCtx *const p_ctx) {
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, -1, -1, -1 /*output_options*/,
data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
if (p_ctx->generate) {
printf(" /*%3d*/ { %s, \"%s\", %s, %d, %d, \"%s\",\n",
i, testUtilBarcodeName(data[i].symbology), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
printf(" /*%3d*/ { %s, \"%s\", %s, %d, %d, %d, \"%s\",\n",
i, testUtilBarcodeName(data[i].symbology),
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n",
i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n",
i, symbol->width, data[i].expected_width, data[i].data);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n",
i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d %s not BWIPP compatible (%s)\n",
i, testUtilBarcodeName(symbol->symbology), data[i].comment);
}
} else {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf,
sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n",
i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf,
data[i].expected);
}
}
}
}
+1
View File
@@ -1752,6 +1752,7 @@ static void test_fuzz(const testCtx *const p_ctx) {
"\136\136",
162, ZINT_ERROR_TOO_LONG, "Error 341: Input too long, requires 167 symbol characters (maximum 102)", 3
}, /* fuzz_data (2nd, 2026-01-12) */
/* 1*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, -1, "\\^CC\\^177#", -1, 0, "", 3 },
};
const int data_size = ARRAY_SIZE(data);
int i, length, ret;
+4 -4
View File
@@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2019-2025 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2019-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -72,7 +72,7 @@ static void test_large(const testCtx *const p_ctx) {
/* 20*/ { BARCODE_PLANET, "1", 13, 0, 2, 143, "" },
/* 21*/ { BARCODE_PLANET, "1", 14, ZINT_WARN_NONCOMPLIANT, 2, 153, "Warning 478: Input length 14 is not standard (should be 11 or 13 digits)" },
/* 22*/ { BARCODE_PLANET, "1", 38, ZINT_WARN_NONCOMPLIANT, 2, 393, "Warning 478: Input length 38 is not standard (should be 11 or 13 digits)" },
/* 23*/ { BARCODE_PLANET, "1", 39, ZINT_ERROR_TOO_LONG, -1, -1, "Error 482: Input length 39 too long (maximum 38)" },
/* 23*/ { BARCODE_PLANET, "1", 39, ZINT_ERROR_TOO_LONG, -1, -1, "Error 480: Input length 39 too long (maximum 38)" },
/* 24*/ { BARCODE_KIX, "1", 18, 0, 3, 143, "" },
/* 25*/ { BARCODE_KIX, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1, "Error 490: Input length 19 too long (maximum 18)" },
/* 26*/ { BARCODE_DAFT, "D", 576, 0, 3, 1151, "" },
@@ -352,10 +352,10 @@ static void test_input(const testCtx *const p_ctx) {
/* 34*/ { BARCODE_PLANET, -1, 0, "1234567890", ZINT_WARN_NONCOMPLIANT, 2, 113, 12, "Warning 478: Input length 10 is not standard (should be 11 or 13 digits)", 0, "BWIPP requires standard lengths" },
/* 35*/ { BARCODE_PLANET, -1, 0, "123456789012", ZINT_WARN_NONCOMPLIANT, 2, 133, 12, "Warning 478: Input length 12 is not standard (should be 11 or 13 digits)", 0, "BWIPP requires standard lengths" },
/* 36*/ { BARCODE_PLANET, -1, 0, "12345678901234", ZINT_WARN_NONCOMPLIANT, 2, 153, 12, "Warning 478: Input length 14 is not standard (should be 11 or 13 digits)", 0, "BWIPP requires standard lengths" },
/* 37*/ { BARCODE_PLANET, -1, 0, "1234567890A", ZINT_ERROR_INVALID_DATA, -1, -1, -1, "Error 483: Invalid character at position 11 in input (digits only)", 1, "" },
/* 37*/ { BARCODE_PLANET, -1, 0, "1234567890A", ZINT_ERROR_INVALID_DATA, -1, -1, -1, "Error 481: Invalid character at position 11 in input (digits only)", 1, "" },
/* 38*/ { BARCODE_KIX, -1, 0, "0123456789ABCDEFGH", 0, 3, 143, 8, "", 1, "" },
/* 39*/ { BARCODE_KIX, -1, 0, "a", 0, 3, 7, 8, "", 1, "" }, /* Converts to upper */
/* 40*/ { BARCODE_KIX, -1, 0, ",", ZINT_ERROR_INVALID_DATA, -1, -1, -1, "Error 491: Invalid character at position 1 in input (alphanumerics only)", 1, "" },
/* 40*/ { BARCODE_KIX, -1, 0, ",", ZINT_ERROR_INVALID_DATA, -1, -1, -1, "Error 489: Invalid character at position 1 in input (alphanumerics only)", 1, "" },
/* 41*/ { BARCODE_DAFT, -1, 0, "DAFT", 0, 3, 7, 8, "", 1, "" },
/* 42*/ { BARCODE_DAFT, -1, 0, "a", 0, 3, 1, 8, "", 1, "" }, /* Converts to upper */
/* 43*/ { BARCODE_DAFT, -1, 0, "B", ZINT_ERROR_INVALID_DATA, -1, -1, -1, "Error 493: Invalid character at position 1 in input (\"D\", \"A\", \"F\" and \"T\" only)", 1, "" },
+5
View File
@@ -3262,6 +3262,11 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
bwipp_opts = bwipp_opts_buf;
}
}
/* Check for Null - for when supported by BWIPP */
for (i = 0; i < 8 && data[i] == '0'; i++);
if (i == 8) {
prefix = "00";
}
memmove(bwipp_data + 2, bwipp_data, data_len + 1);
memmove(bwipp_data, prefix, 2);
}
+20 -11
View File
@@ -1,7 +1,7 @@
/* upcean.c - Handles UPC, EAN and ISBN */
/*
libzint - the open source barcode library
Copyright (C) 2008-2025 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2008-2026 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -85,6 +85,8 @@ static const char EANsetB[10][4] = {
{'1','3','2','1'}, {'4','1','1','1'}, {'2','1','3','1'}, {'3','1','2','1'}, {'2','1','1','3'}
};
static const char EANones[6] = { '1','1','1','1','1','1' }; /* Various lengths used for start/stop/separators */
/* Write UPC-A or EAN-8 encodation to destination `d` */
static void upca_set_dest(const unsigned char source[], const int length, char *d) {
int i, half_way;
@@ -92,13 +94,13 @@ static void upca_set_dest(const unsigned char source[], const int length, char *
half_way = length / 2;
/* Start character */
memcpy(d, "111", 3);
memcpy(d, EANones, 3);
d += 3;
for (i = 0; i < length; i++, d += 4) {
if (i == half_way) {
/* Middle character - separates manufacturer no. from product no. - also inverts right hand characters */
memcpy(d, "11111", 5);
memcpy(d, EANones, 5);
d += 5;
}
@@ -106,7 +108,9 @@ static void upca_set_dest(const unsigned char source[], const int length, char *
}
/* Stop character */
memcpy(d, "111", 4); /* Include terminating NUL */
memcpy(d, EANones, 3);
d += 3;
*d = '\0'; /* Need to NUL-terminate */
}
/* Make a UPC-A barcode, allowing for composite if `cc_rows` set */
@@ -278,7 +282,7 @@ static int upce_cc(struct zint_symbol *symbol, unsigned char source[], int lengt
/* Take all this information and make the barcode pattern */
/* Start character */
memcpy(d, "111", 3);
memcpy(d, EANones, 3);
d += 3;
for (i = 0; i < length; i++, d += 4) {
@@ -293,7 +297,9 @@ static int upce_cc(struct zint_symbol *symbol, unsigned char source[], int lengt
}
/* Stop character */
memcpy(d, "111111", 7); /* Include terminating NUL */
memcpy(d, EANones, 6);
d += 6;
*d = '\0'; /* Need to NUL-terminate */
z_hrt_cat_chr_nochk(symbol, check_digit);
@@ -333,6 +339,7 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], int length,
/* EAN-2 and EAN-5 add-on codes */
static void ean_add_on(const unsigned char source[], const int length, char dest[], const int addon_gap) {
static const char start[3] = { '1','1','2' };
const char *parity;
int i;
char *d = dest + strlen(dest);
@@ -343,7 +350,7 @@ static void ean_add_on(const unsigned char source[], const int length, char dest
}
/* Start character */
memcpy(d, "112", 3);
memcpy(d, start, 3);
d += 3;
/* Calculate parity */
@@ -381,7 +388,7 @@ static void ean_add_on(const unsigned char source[], const int length, char dest
/* Glyph separator */
if (i != (length - 1)) {
memcpy(d, "11", 2);
memcpy(d, EANones, 2);
d += 2;
}
}
@@ -422,13 +429,13 @@ static int ean13_cc(struct zint_symbol *symbol, const unsigned char source[], in
half_way = 7;
/* Start character */
memcpy(d, "111", 3);
memcpy(d, EANones, 3);
d += 3;
for (i = 1; i < symbol->text_length; i++, d += 4) {
if (i == half_way) {
/* Middle character - separates manufacturer no. from product no. - also inverts right hand characters */
memcpy(d, "11111", 5);
memcpy(d, EANones, 5);
d += 5;
}
@@ -440,7 +447,9 @@ static int ean13_cc(struct zint_symbol *symbol, const unsigned char source[], in
}
/* Stop character */
memcpy(d, "111", 4); /* Include terminating NUL */
memcpy(d, EANones, 3);
d += 3;
*d = '\0'; /* Need to NUL-terminate */
if (symbol->output_options & COMPLIANT_HEIGHT) {
/* ISO/IEC 15420:2009 4.3.3 Bar height EAN-13 22.85mm / 0.33mm (X) ~ 69.24,
+11 -7
View File
@@ -6086,7 +6086,8 @@ alt="zint -b AUSPOST --compliantheight -d &quot;96184209&quot;" />
Control Code (FCC) is added by Zint and should not be included in the
input data. Reed-Solomon error correction data is generated by Zint.
Encoding behaviour is determined by the length of the input data
according to the formula shown in the following table.</p>
according to the formula shown in the following table. The first 8
digits is the DPID.</p>
<table id="tbl:auspost_input_formats" style="width:86%;">
<caption><span class="table-label">Table 23:</span> Australia Post Input
Formats</caption>
@@ -6103,7 +6104,7 @@ Formats</caption>
<th style="text-align: left;">Required Input Format</th>
<th>Symbol Length</th>
<th>FCC</th>
<th style="text-align: left;">Encoding Table</th>
<th>Encoding Table(s)</th>
</tr>
</thead>
<tbody>
@@ -6112,38 +6113,41 @@ Formats</caption>
<td style="text-align: left;"><code>99999999</code></td>
<td>37-bar</td>
<td>11</td>
<td style="text-align: left;">None</td>
<td>N</td>
</tr>
<tr>
<td style="text-align: left;">13</td>
<td style="text-align: left;"><code>99999999AAAAA</code></td>
<td>52-bar</td>
<td>59</td>
<td style="text-align: left;">C</td>
<td>N and C</td>
</tr>
<tr>
<td style="text-align: left;">16</td>
<td style="text-align: left;"><code>9999999999999999</code></td>
<td>52-bar</td>
<td>59</td>
<td style="text-align: left;">N</td>
<td>N</td>
</tr>
<tr>
<td style="text-align: left;">18</td>
<td style="text-align: left;"><code>99999999AAAAAAAAAA</code></td>
<td>67-bar</td>
<td>62</td>
<td style="text-align: left;">C</td>
<td>N and C</td>
</tr>
<tr>
<td style="text-align: left;">23</td>
<td style="text-align: left;"><code>99999999999999999999999</code></td>
<td>67-bar</td>
<td>62</td>
<td style="text-align: left;">N</td>
<td>N</td>
</tr>
</tbody>
</table>
<p>The special Null FCC 00, non-machine readable and intended for
customer use only, is used (all input lengths) if the DPID is all
zeroes.</p>
<h4 id="reply-paid-barcode">6.5.1.2 Reply Paid Barcode</h4>
<p>A Reply Paid version of the Australia Post 4-State Barcode (FCC 45)
which requires an 8-digit DPID input.</p>
+8 -5
View File
@@ -4142,25 +4142,28 @@ Valid data characters are 0-9, A-Z, a-z, space and hash (#). A Format Control
Code (FCC) is added by Zint and should not be included in the input data.
Reed-Solomon error correction data is generated by Zint. Encoding behaviour is
determined by the length of the input data according to the formula shown in the
following table.
following table. The first 8 digits is the DPID.
-------------------------------------------------------------
Input Required Input Format Symbol FCC Encoding
Length Length Table
Length Length Table(s)
------ ------------------------- ------ --- --------
8 `99999999` 37-bar 11 None
8 `99999999` 37-bar 11 N
13 `99999999AAAAA` 52-bar 59 C
13 `99999999AAAAA` 52-bar 59 N and C
16 `9999999999999999` 52-bar 59 N
18 `99999999AAAAAAAAAA` 67-bar 62 C
18 `99999999AAAAAAAAAA` 67-bar 62 N and C
23 `99999999999999999999999` 67-bar 62 N
-------------------------------------------------------------
Table: Australia Post Input Formats {#tbl:auspost_input_formats}
The special Null FCC 00, non-machine readable and intended for customer use
only, is used (all input lengths) if the DPID is all zeroes.
#### 6.5.1.2 Reply Paid Barcode
A Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which
+8 -5
View File
@@ -3949,25 +3949,28 @@ Valid data characters are 0-9, A-Z, a-z, space and hash (#). A Format Control
Code (FCC) is added by Zint and should not be included in the input data.
Reed-Solomon error correction data is generated by Zint. Encoding behaviour is
determined by the length of the input data according to the formula shown in the
following table.
following table. The first 8 digits is the DPID.
---------------------------------------------------------------
Input Required Input Format Symbol FCC Encoding
Length Length Table
Length Length Table(s)
--------- --------------------------- -------- ----- ----------
8 99999999 37-bar 11 None
8 99999999 37-bar 11 N
13 99999999AAAAA 52-bar 59 C
13 99999999AAAAA 52-bar 59 N and C
16 9999999999999999 52-bar 59 N
18 99999999AAAAAAAAAA 67-bar 62 C
18 99999999AAAAAAAAAA 67-bar 62 N and C
23 99999999999999999999999 67-bar 62 N
---------------------------------------------------------------
Table 23: Australia Post Input Formats
The special Null FCC 00, non-machine readable and intended for customer use
only, is used (all input lengths) if the DPID is all zeroes.
6.5.1.2 Reply Paid Barcode
A Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which