POSTNET/PLANET: allow up to 38 chars (ZINT_WARN_NONCOMPLIANT) (see [d7ac9c])

This commit is contained in:
gitlost 2021-07-13 19:56:53 +01:00
parent 7cc2095d3c
commit ef6e1ca1e3
4 changed files with 110 additions and 93 deletions

View File

@ -84,7 +84,7 @@ static const char *JapanTable[19] = {
};
/* Set height for POSTNET/PLANET codes, maintaining ratio */
static int usps_set_height(struct zint_symbol *symbol) {
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
Spacing
http://web.archive.org/web/20061113174253/http://pe.usps.com/cpim/ftp/manuals/dmm300/full/mailingStandards.pdf
@ -117,8 +117,12 @@ static int usps_set_height(struct zint_symbol *symbol) {
#ifdef COMPLIANT_HEIGHTS
if (symbol->height < 4.6f || symbol->height > 9.0f) {
error_number = ZINT_WARN_NONCOMPLIANT;
if (!no_errtxt) {
strcpy(symbol->errtxt, "498: Height not compliant with standards");
}
}
#else
(void)&no_errtxt;
#endif
return error_number;
@ -127,16 +131,19 @@ static int usps_set_height(struct zint_symbol *symbol) {
/* Handles the PostNet system used for Zip codes in the US */
static int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
int i, sum, check_digit;
int error_number;
int error_number = 0;
if (length != 5 && length != 9 && length != 11) {
strcpy(symbol->errtxt, "480: Input wrong length (5, 9 or 11 characters only)");
if (length > 38) {
strcpy(symbol->errtxt, "480: Input too long (38 character maximum)");
return ZINT_ERROR_TOO_LONG;
}
error_number = is_sane(NEON, source, length);
if (error_number == ZINT_ERROR_INVALID_DATA) {
if (length != 5 && length != 9 && length != 11) {
strcpy(symbol->errtxt, "479: Input length is not standard (5, 9 or 11 characters)");
error_number = ZINT_WARN_NONCOMPLIANT;
}
if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "481: Invalid character in data (digits only)");
return error_number;
return ZINT_ERROR_INVALID_DATA;
}
sum = 0;
@ -159,13 +166,13 @@ static int postnet(struct zint_symbol *symbol, unsigned char source[], char dest
/* Puts PostNet barcodes into the pattern matrix */
INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
unsigned int loopey, h;
int writer;
int error_number;
int error_number, warn_number;
error_number = postnet(symbol, source, height_pattern, length);
if (error_number != 0) {
if (error_number >= ZINT_ERROR) {
return error_number;
}
@ -178,26 +185,29 @@ INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int l
set_module(symbol, 1, writer);
writer += 2;
}
error_number = usps_set_height(symbol);
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
symbol->rows = 2;
symbol->width = writer - 1;
return error_number;
return error_number ? error_number : warn_number;
}
/* Handles the PLANET system used for item tracking in the US */
static int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
int i, sum, check_digit;
int error_number;
int error_number = 0;
if (length != 11 && length != 13) {
strcpy(symbol->errtxt, "482: Input wrong length (11 or 13 characters only)");
if (length > 38) {
strcpy(symbol->errtxt, "482: Input too long (38 character maximum)");
return ZINT_ERROR_TOO_LONG;
}
error_number = is_sane(NEON, source, length);
if (error_number == ZINT_ERROR_INVALID_DATA) {
if (length != 11 && length != 13) {
strcpy(symbol->errtxt, "478: Input length is not standard (11 or 13 characters)");
error_number = ZINT_WARN_NONCOMPLIANT;
}
if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "483: Invalid character in data (digits only)");
return error_number;
return ZINT_ERROR_INVALID_DATA;
}
sum = 0;
@ -220,13 +230,13 @@ static int planet(struct zint_symbol *symbol, unsigned char source[], char dest[
/* Puts PLANET barcodes into the pattern matrix */
INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
unsigned int loopey, h;
int writer;
int error_number;
int error_number, warn_number;
error_number = planet(symbol, source, height_pattern, length);
if (error_number != 0) {
if (error_number >= ZINT_ERROR) {
return error_number;
}
@ -239,11 +249,11 @@ INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int
set_module(symbol, 1, writer);
writer += 2;
}
error_number = usps_set_height(symbol);
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
symbol->rows = 2;
symbol->width = writer - 1;
return error_number;
return error_number ? error_number : warn_number;
}
/* Korean Postal Authority */

View File

@ -95,7 +95,7 @@ static void test_checks(int index, int debug) {
/* 40*/ { 36, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA },
/* 41*/ { 39, -1, "1", -1, -1, -1, -1, -1, 0, "", BARCODE_UPCE },
/* 42*/ { 39, -1, "1", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCE },
/* 43*/ { 41, -1, "1", -1, -1, -1, -1, -1, ZINT_ERROR_TOO_LONG, "Error 480: Input wrong length (5, 9 or 11 characters only)", BARCODE_POSTNET },
/* 43*/ { 41, -1, "1", -1, -1, -1, -1, -1, ZINT_WARN_NONCOMPLIANT, "Warning 479: Input length is not standard (5, 9 or 11 characters)", BARCODE_POSTNET },
/* 44*/ { 41, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },
/* 45*/ { 41, -1, "12345", -1, -1, -1, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET },
/* 46*/ { 42, -1, "12345", -1, -1, -1, -1, -1, 0, "", BARCODE_POSTNET },

View File

@ -50,21 +50,25 @@ static void test_large(int index, int debug) {
/* 0*/ { BARCODE_FLAT, "1", 90, 0, 1, 810 },
/* 1*/ { BARCODE_FLAT, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { BARCODE_POSTNET, "1", 11, 0, 2, 123 },
/* 3*/ { BARCODE_POSTNET, "1", 12, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 4*/ { BARCODE_FIM, "D", 1, 0, 1, 17 },
/* 5*/ { BARCODE_FIM, "D", 2, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { BARCODE_RM4SCC, "1", 50, 0, 3, 411 },
/* 7*/ { BARCODE_RM4SCC, "1", 51, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { BARCODE_JAPANPOST, "1", 20, 0, 3, 133 },
/* 9*/ { BARCODE_JAPANPOST, "1", 21, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { BARCODE_KOREAPOST, "1", 6, 0, 1, 162 },
/* 11*/ { BARCODE_KOREAPOST, "1", 7, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 12*/ { BARCODE_PLANET, "1", 13, 0, 2, 143 },
/* 13*/ { BARCODE_PLANET, "1", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { BARCODE_KIX, "1", 18, 0, 3, 143 },
/* 15*/ { BARCODE_KIX, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 16*/ { BARCODE_DAFT, "D", 50, 0, 3, 99 },
/* 17*/ { BARCODE_DAFT, "D", 51, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 3*/ { BARCODE_POSTNET, "1", 12, ZINT_WARN_NONCOMPLIANT, 2, 133 },
/* 4*/ { BARCODE_POSTNET, "1", 38, ZINT_WARN_NONCOMPLIANT, 2, 393 },
/* 5*/ { BARCODE_POSTNET, "1", 39, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { BARCODE_FIM, "D", 1, 0, 1, 17 },
/* 7*/ { BARCODE_FIM, "D", 2, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { BARCODE_RM4SCC, "1", 50, 0, 3, 411 },
/* 9*/ { BARCODE_RM4SCC, "1", 51, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { BARCODE_JAPANPOST, "1", 20, 0, 3, 133 },
/* 11*/ { BARCODE_JAPANPOST, "1", 21, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 12*/ { BARCODE_KOREAPOST, "1", 6, 0, 1, 162 },
/* 13*/ { BARCODE_KOREAPOST, "1", 7, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { BARCODE_PLANET, "1", 13, 0, 2, 143 },
/* 15*/ { BARCODE_PLANET, "1", 14, ZINT_WARN_NONCOMPLIANT, 2, 153 },
/* 16*/ { BARCODE_PLANET, "1", 38, ZINT_WARN_NONCOMPLIANT, 2, 393 },
/* 17*/ { BARCODE_PLANET, "1", 39, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 18*/ { BARCODE_KIX, "1", 18, 0, 3, 143 },
/* 19*/ { BARCODE_KIX, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 20*/ { BARCODE_DAFT, "D", 50, 0, 3, 99 },
/* 21*/ { BARCODE_DAFT, "D", 51, ZINT_ERROR_TOO_LONG, -1, -1 },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -213,36 +217,38 @@ static void test_input(int index, int debug) {
/* 2*/ { BARCODE_POSTNET, "12345", 0, 2, 63 },
/* 3*/ { BARCODE_POSTNET, "123457689", 0, 2, 103 },
/* 4*/ { BARCODE_POSTNET, "12345768901", 0, 2, 123 },
/* 5*/ { BARCODE_POSTNET, "1234", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { BARCODE_POSTNET, "123456", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 7*/ { BARCODE_POSTNET, "123456789012", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { BARCODE_POSTNET, "1234A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 9*/ { BARCODE_FIM, "a", 0, 1, 17 },
/* 10*/ { BARCODE_FIM, "b", 0, 1, 17 },
/* 11*/ { BARCODE_FIM, "c", 0, 1, 17 },
/* 12*/ { BARCODE_FIM, "d", 0, 1, 17 },
/* 13*/ { BARCODE_FIM, "ad", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { BARCODE_FIM, "e", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 15*/ { BARCODE_RM4SCC, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, 3, 299 },
/* 16*/ { BARCODE_RM4SCC, "a", 0, 3, 19 }, // Converts to upper
/* 17*/ { BARCODE_RM4SCC, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 18*/ { BARCODE_JAPANPOST, "1234567890-ABCDEFGH", 0, 3, 133 },
/* 19*/ { BARCODE_JAPANPOST, "a", 0, 3, 133 }, // Converts to upper
/* 20*/ { BARCODE_JAPANPOST, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 21*/ { BARCODE_KOREAPOST, "123456", 0, 1, 167 },
/* 22*/ { BARCODE_KOREAPOST, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 23*/ { BARCODE_PLANET, "12345678901", 0, 2, 123 },
/* 24*/ { BARCODE_PLANET, "1234567890123", 0, 2, 143 },
/* 25*/ { BARCODE_PLANET, "1234567890", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 26*/ { BARCODE_PLANET, "123456789012", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 27*/ { BARCODE_PLANET, "12345678901234", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 28*/ { BARCODE_PLANET, "1234567890A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 29*/ { BARCODE_KIX, "0123456789ABCDEFGH", 0, 3, 143 },
/* 30*/ { BARCODE_KIX, "a", 0, 3, 7 }, // Converts to upper
/* 31*/ { BARCODE_KIX, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 32*/ { BARCODE_DAFT, "DAFT", 0, 3, 7 },
/* 33*/ { BARCODE_DAFT, "a", 0, 3, 1 }, // Converts to upper
/* 34*/ { BARCODE_DAFT, "B", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 5*/ { BARCODE_POSTNET, "0", ZINT_WARN_NONCOMPLIANT, 2, 23 },
/* 6*/ { BARCODE_POSTNET, "1234", ZINT_WARN_NONCOMPLIANT, 2, 53 },
/* 7*/ { BARCODE_POSTNET, "123456", ZINT_WARN_NONCOMPLIANT, 2, 73 },
/* 8*/ { BARCODE_POSTNET, "123456789012", ZINT_WARN_NONCOMPLIANT, 2, 133 },
/* 9*/ { BARCODE_POSTNET, "1234A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 10*/ { BARCODE_FIM, "a", 0, 1, 17 },
/* 11*/ { BARCODE_FIM, "b", 0, 1, 17 },
/* 12*/ { BARCODE_FIM, "c", 0, 1, 17 },
/* 13*/ { BARCODE_FIM, "d", 0, 1, 17 },
/* 14*/ { BARCODE_FIM, "ad", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 15*/ { BARCODE_FIM, "e", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 16*/ { BARCODE_RM4SCC, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, 3, 299 },
/* 17*/ { BARCODE_RM4SCC, "a", 0, 3, 19 }, // Converts to upper
/* 18*/ { BARCODE_RM4SCC, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 19*/ { BARCODE_JAPANPOST, "1234567890-ABCDEFGH", 0, 3, 133 },
/* 20*/ { BARCODE_JAPANPOST, "a", 0, 3, 133 }, // Converts to upper
/* 21*/ { BARCODE_JAPANPOST, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 22*/ { BARCODE_KOREAPOST, "123456", 0, 1, 167 },
/* 23*/ { BARCODE_KOREAPOST, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 24*/ { BARCODE_PLANET, "12345678901", 0, 2, 123 },
/* 25*/ { BARCODE_PLANET, "1234567890123", 0, 2, 143 },
/* 26*/ { BARCODE_PLANET, "0", ZINT_WARN_NONCOMPLIANT, 2, 23 },
/* 27*/ { BARCODE_PLANET, "1234567890", ZINT_WARN_NONCOMPLIANT, 2, 113 },
/* 28*/ { BARCODE_PLANET, "123456789012", ZINT_WARN_NONCOMPLIANT, 2, 133 },
/* 29*/ { BARCODE_PLANET, "12345678901234", ZINT_WARN_NONCOMPLIANT, 2, 153 },
/* 30*/ { BARCODE_PLANET, "1234567890A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 31*/ { BARCODE_KIX, "0123456789ABCDEFGH", 0, 3, 143 },
/* 32*/ { BARCODE_KIX, "a", 0, 3, 7 }, // Converts to upper
/* 33*/ { BARCODE_KIX, ",", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 34*/ { BARCODE_DAFT, "DAFT", 0, 3, 7 },
/* 35*/ { BARCODE_DAFT, "a", 0, 3, 1 }, // Converts to upper
/* 36*/ { BARCODE_DAFT, "B", ZINT_ERROR_INVALID_DATA, -1, -1 },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;

View File

@ -905,15 +905,15 @@ The functions for encoding and printing barcodes are defined as:
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source,
int length);
int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename);
int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename);
int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);
int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *source,
int length, int rotate_angle);
int ZBarcode_Encode_and_Print(struct zint_symbol *symbol,
const unsigned char *source, int length, int rotate_angle);
int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename,
int rotate_angle);
int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol,
const char *filename, int rotate_angle);
In these definitions "length" can be used to set the length of the input
string. This allows the encoding of NUL (ASCII 0) characters in those
@ -940,10 +940,10 @@ allow you to do this:
int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle);
int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol,
unsigned char *source, int length, int rotate_angle);
const unsigned char *source, int length, int rotate_angle);
int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename,
int rotate_angle);
int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol,
const char *filename, int rotate_angle);
The arguments here are the same as above. The difference is that instead of
saving the image to file it is placed in an unsigned character array. The
@ -993,10 +993,10 @@ you to do this:
int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle);
int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol,
unsigned char *source, int length, int rotate_angle);
const unsigned char *source, int length, int rotate_angle);
int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol,
char *filename, int rotate_angle);
const char *filename, int rotate_angle);
Here the "vector" pointer is set to a header which contains pointers to lists
of structures representing the various elements of the barcode: rectangles,
@ -2154,17 +2154,18 @@ symbology is able to encode whole numbers between 4 and 64570080.
Used by the United States Postal Service until 2009, the POSTNET barcode was
used for encoding zip-codes on mail items. POSTNET uses numerical input data
and includes a modulo-10 check digit. While Zint will encode POSTNET symbols of
any length, standard lengths as used by USPS were PostNet6 (5 digits ZIP
input), PostNet10 (5 digit ZIP + 4 digit user data) and PostNet12 (5 digit ZIP
+ 6 digit user data).
up to 38 digits in length, standard lengths as used by USPS were PostNet6 (5
digit ZIP input), PostNet10 (5 digit ZIP + 4 digit user data) and PostNet12 (5
digit ZIP + 6 digit user data).
6.4.3 PLANET
------------
Used by the United States Postal Service until 2009, the PLANET (Postal Alpha
Numeric Encoding Technique) barcode was used for encoding routing data on mail
items. PLANET uses numerical input data and includes a modulo-10 check digit.
While Zint will encode PLANET symbols of any length, standard lengths used by
USPS were Planet12 (11 digit input) and Planet14 (13 digit input).
While Zint will encode PLANET symbols of up to 38 digits in length, standard
lengths used by USPS were Planet12 (11 digit input) and Planet14 (13 digit
input).
6.5 4-State Postal Codes
------------------------
@ -2259,14 +2260,14 @@ A-Z and Dash (-). A modulo 19 check digit is added by Zint.
-----------------------------
Also known as Semacode this symbology was developed in 1989 by Acuity CiMatrix
in partnership with the US DoD and NASA. The symbol can encode a large amount
of data in a small area. Data Matrix can encode characters in the
Latin-1 set by default but also supports encoding using other character sets
using the ECI mechanism. It can also encode GS1 data. The size of the
generated symbol can also be adjusted using the --vers= option or by setting
option_2 as shown in the table below. A separate symbology ID can be used to
encode Health Industry Barcode (HIBC) data which adds a leading '+' character
and a modulo-49 check digit to the encoded data. Note that only ECC200 encoding
is supported, the older standards have now been removed from Zint.
of data in a small area. Data Matrix encodes characters in the Latin-1 set by
default but also supports encoding in other character sets using the ECI
mechanism. It can also encode GS1 data. The size of the generated symbol can
also be adjusted using the --vers= option or by setting option_2 as shown in the
table below. A separate symbology ID can be used to encode Health Industry
Barcode (HIBC) data which adds a leading '+' character and a modulo-49 check
digit to the encoded data. Note that only ECC200 encoding is supported, the
older standards have now been removed from Zint.
---------------------
Input | Symbol Size