diff --git a/backend/bmp.c b/backend/bmp.c index 07bc7e14..b750c654 100644 --- a/backend/bmp.c +++ b/backend/bmp.c @@ -39,7 +39,7 @@ #include #endif -INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { +INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { int i, row, column; int row_size; int bits_per_pixel; diff --git a/backend/common.c b/backend/common.c index b082eb63..4011e1a0 100644 --- a/backend/common.c +++ b/backend/common.c @@ -49,7 +49,7 @@ INTERNAL int ctoi(const char source) { /* Convert an integer value to a string representing its binary equivalent */ INTERNAL void bin_append(const int arg, const int length, char *binary) { - size_t posn = strlen(binary); + int posn = (int) strlen(binary); bin_append_posn(arg, length, binary, posn); @@ -57,7 +57,7 @@ INTERNAL void bin_append(const int arg, const int length, char *binary) { } /* Convert an integer value to a string representing its binary equivalent at a set position */ -INTERNAL void bin_append_posn(const int arg, const int length, char *binary, size_t posn) { +INTERNAL int bin_append_posn(const int arg, const int length, char *binary, int posn) { int i; int start; @@ -70,6 +70,7 @@ INTERNAL void bin_append_posn(const int arg, const int length, char *binary, siz binary[posn + i] = '0'; } } + return posn + length; } /* Converts an integer value to its hexadecimal character */ @@ -137,28 +138,31 @@ INTERNAL int posn(const char set_string[], const char data) { return -1; } -/* Return true (1-8) if a module is dark/black/colour, otherwise false (0) */ +#ifndef COMMON_INLINE +/* Return true (1) if a module is dark/black, otherwise false (0) */ INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) { - if (symbol->symbology == BARCODE_ULTRA) { - return symbol->encoded_data[y_coord][x_coord]; - } else { - return (symbol->encoded_data[y_coord][x_coord / 8] >> (x_coord % 8)) & 1; - } + return (symbol->encoded_data[y_coord][x_coord >> 3] >> (x_coord & 0x07)) & 1; } /* Set a module to dark/black */ INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) { - symbol->encoded_data[y_coord][x_coord / 8] |= 1 << (x_coord % 8); + symbol->encoded_data[y_coord][x_coord >> 3] |= 1 << (x_coord & 0x07); +} + +/* Return true (1-8) if a module is colour, otherwise false (0) */ +INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) { + return symbol->encoded_data[y_coord][x_coord]; } /* Set a module to a colour */ INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord, const int colour) { symbol->encoded_data[y_coord][x_coord] = colour; } +#endif /* Set a dark/black module to white (i.e. unset) */ INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) { - symbol->encoded_data[y_coord][x_coord / 8] &= ~(1 << (x_coord % 8)); + symbol->encoded_data[y_coord][x_coord >> 3] &= ~(1 << (x_coord & 0x07)); } /* Expands from a width pattern to a bit pattern */ diff --git a/backend/common.h b/backend/common.h index 52b59cdf..c64a8a57 100644 --- a/backend/common.h +++ b/backend/common.h @@ -67,6 +67,22 @@ #define STATIC_UNLESS_ZINT_TEST static #endif +#define COMMON_INLINE 1 + +#ifdef COMMON_INLINE +/* Return true (1) if a module is dark/black, otherwise false (0) */ +#define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1) + +/* Set a module to dark/black */ +#define set_module(s, y, x) do { (s)->encoded_data[(y)][(x) >> 3] |= 1 << ((x) & 0x07); } while (0) + +/* Return true (1-8) if a module is colour, otherwise false (0) */ +#define module_colour_is_set(s, y, x) ((s)->encoded_data[(y)][(x)]) + +/* Set a module to a colour */ +#define set_module_colour(s, y, x, c) do { (s)->encoded_data[(y)][(x)] = (c); } while (0) +#endif + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -77,11 +93,14 @@ extern "C" { INTERNAL int is_sane(const char test_string[], const unsigned char source[], const size_t length); INTERNAL void lookup(const char set_string[], const char *table[], const char data, char dest[]); INTERNAL void bin_append(const int arg, const int length, char *binary); - INTERNAL void bin_append_posn(const int arg, const int length, char *binary, size_t posn); + INTERNAL int bin_append_posn(const int arg, const int length, char *binary, int posn); INTERNAL int posn(const char set_string[], const char data); + #ifndef COMMON_INLINE INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord); + INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord, const int colour); + #endif INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL void expand(struct zint_symbol *symbol, const char data[]); INTERNAL int is_stackable(const int symbology); diff --git a/backend/composite.h b/backend/composite.h index 5fa610f8..c202322d 100644 --- a/backend/composite.h +++ b/backend/composite.h @@ -67,7 +67,7 @@ static const char aRAPTable[68] = { /* Row Address Patterns are as defined in pdf417.h */ /* Generated by tools/gen_pwr928_table.php */ -static UINT pwr928[69][7] = { +static const UINT pwr928[69][7] = { { 0, 0, 0, 0, 0, 0, 1, }, { 0, 0, 0, 0, 0, 0, 2, }, { 0, 0, 0, 0, 0, 0, 4, }, diff --git a/backend/gif.c b/backend/gif.c index 9d5c7476..ddfcd045 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -273,7 +273,7 @@ static int gif_lzw(statestruct *pState, int paletteBitSize) { /* * Called function to save in gif format */ -INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { +INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { unsigned char outbuf[10]; FILE *gif_file; unsigned short usTemp; @@ -290,6 +290,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { unsigned char backgroundColourIndex; unsigned char RGBCur[3]; + unsigned char RGBUnused[3] = {0,0,0}; int colourIndex; @@ -525,8 +526,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { fwrite(paletteRGB, 3*paletteCount, 1, gif_file); /* add unused palette items to fill palette size */ for (paletteIndex = paletteCount; paletteIndex < paletteSize; paletteIndex++) { - unsigned char RGBCur[3] = {0,0,0}; - fwrite(RGBCur, 3, 1, gif_file); + fwrite(RGBUnused, 3, 1, gif_file); } /* Graphic control extension (8) */ @@ -580,7 +580,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { fwrite(outbuf, 10, 1, gif_file); /* prepare state array */ - State.pIn = (unsigned char *) pixelbuf; + State.pIn = pixelbuf; State.InLen = symbol->bitmap_height * symbol->bitmap_width; State.pOut = (unsigned char *) lzwoutbuf; State.OutLength = lzoutbufSize; diff --git a/backend/library.c b/backend/library.c index fd0efa4c..4f68bf0a 100644 --- a/backend/library.c +++ b/backend/library.c @@ -32,6 +32,7 @@ #include #include +#include #ifdef _MSC_VER #include #endif @@ -47,6 +48,7 @@ struct zint_symbol *ZBarcode_Create() { if (!symbol) return NULL; memset(symbol, 0, sizeof (*symbol)); + symbol->symbology = BARCODE_CODE128; strcpy(symbol->fgcolour, "000000"); symbol->fgcolor = &symbol->fgcolour[0]; @@ -64,6 +66,7 @@ struct zint_symbol *ZBarcode_Create() { symbol->dot_size = 4.0f / 5.0f; symbol->vector = NULL; symbol->warn_level = WARN_DEFAULT; + return symbol; } @@ -115,7 +118,6 @@ void ZBarcode_Delete(struct zint_symbol *symbol) { INTERNAL int get_best_eci(unsigned char source[], size_t length); /* Calculate suitable ECI mode */ INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */ - INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 3 from 9 (or Code 39) */ INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ @@ -147,8 +149,8 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ INTERNAL int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[],const size_t length); /* Code 16k */ -INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* PDF417 */ -INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length); /* Micro PDF417 */ +INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ +INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ @@ -221,8 +223,14 @@ static int dump_plot(struct zint_symbol *symbol) { int byt = 0; for (i = 0; i < symbol->width; i++) { byt = byt << 1; - if (module_is_set(symbol, r, i)) { - byt += 1; + if (symbol->symbology == BARCODE_ULTRA) { + if (module_colour_is_set(symbol, r, i)) { + byt += 1; + } + } else { + if (module_is_set(symbol, r, i)) { + byt += 1; + } } if (((i + 1) % 4) == 0) { fputc(hex[byt], f); @@ -256,7 +264,7 @@ static int dump_plot(struct zint_symbol *symbol) { static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t length) { size_t i; int counter, error_number; - char to_process[113], temp[2], check_digit; + char to_process[113], check_digit; /* without "+" and check: max 110 characters in HIBC 2.6 */ if (length > 110) { @@ -270,7 +278,6 @@ static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t lengt return error_number; } - strcpy(to_process, "+"); counter = 41; for (i = 0; i < length; i++) { counter += posn(TECHNETIUM, source[i]); @@ -304,26 +311,25 @@ static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t lengt } } - temp[0] = check_digit; - temp[1] = '\0'; - - strcat(to_process, (char *) source); - strcat(to_process, temp); - length = strlen(to_process); + to_process[0] = '+'; + memcpy(to_process + 1, source, length); + to_process[length + 1] = check_digit; + length += 2; + to_process[length] = '\0'; switch (symbol->symbology) { case BARCODE_HIBC_128: error_number = code_128(symbol, (unsigned char *) to_process, length); - ustrcpy(symbol->text, (unsigned char*) "*"); - strcat((char*) symbol->text, to_process); - strcat((char*) symbol->text, "*"); + ustrcpy(symbol->text, "*"); + ustrcat(symbol->text, to_process); + ustrcat(symbol->text, "*"); break; case BARCODE_HIBC_39: symbol->option_2 = 0; error_number = c39(symbol, (unsigned char *) to_process, length); - ustrcpy(symbol->text, (unsigned char*) "*"); - strcat((char*) symbol->text, to_process); - strcat((char*) symbol->text, "*"); + ustrcpy(symbol->text, "*"); + ustrcat(symbol->text, to_process); + ustrcat(symbol->text, "*"); break; case BARCODE_HIBC_DM: error_number = dmatrix(symbol, (unsigned char *) to_process, length); @@ -669,110 +675,29 @@ unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) { int ZBarcode_ValidID(int symbol_id) { /* Checks whether a symbology is supported */ + static const unsigned char ids[146] = { + 0, 1, 2, 3, 4, 0, 6, 7, 8, 9, + 0, 0, 0, 13, 14, 0, 16, 0, 18, 0, + 20, 21, 22, 23, 24, 25, 0, 0, 28, 29, + 30, 31, 32, 0, 34, 35, 0, 37, 38, 0, + 40, 0, 0, 0, 0, 0, 0, 47, 0, 49, + 50, 51, 52, 53, 0, 55, 56, 57, 58, 0, + 60, 0, 0, 63, 0, 0, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 0, 79, + 80, 81, 82, 0, 84, 85, 86, 87, 0, 89, + 90, 0, 92, 93, 0, 0, 96, 97, 98, 99, + 0, 0, 102, 0, 104, 0, 106, 0, 108, 0, + 110, 0, 112, 0, 0, 115, 116, 0, 0, 0, + 0, 121, 0, 0, 0, 0, 0, 0, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, + }; - int result = 0; - - switch (symbol_id) { - case BARCODE_CODE11: - case BARCODE_C25STANDARD: - case BARCODE_C25INTER: - case BARCODE_C25IATA: - case BARCODE_C25LOGIC: - case BARCODE_C25IND: - case BARCODE_CODE39: - case BARCODE_EXCODE39: - case BARCODE_EANX: - case BARCODE_EANX_CHK: - case BARCODE_GS1_128: - case BARCODE_CODABAR: - case BARCODE_CODE128: - case BARCODE_DPLEIT: - case BARCODE_DPIDENT: - case BARCODE_CODE16K: - case BARCODE_CODE49: - case BARCODE_CODE93: - case BARCODE_FLAT: - case BARCODE_DBAR_OMN: - case BARCODE_DBAR_LTD: - case BARCODE_DBAR_EXP: - case BARCODE_TELEPEN: - case BARCODE_UPCA: - case BARCODE_UPCA_CHK: - case BARCODE_UPCE: - case BARCODE_UPCE_CHK: - case BARCODE_POSTNET: - case BARCODE_MSI_PLESSEY: - case BARCODE_FIM: - case BARCODE_LOGMARS: - case BARCODE_PHARMA: - case BARCODE_PZN: - case BARCODE_PHARMA_TWO: - case BARCODE_PDF417: - case BARCODE_PDF417COMP: - case BARCODE_MAXICODE: - case BARCODE_QRCODE: - case BARCODE_CODE128B: - case BARCODE_AUSPOST: - case BARCODE_AUSREPLY: - case BARCODE_AUSROUTE: - case BARCODE_AUSREDIRECT: - case BARCODE_ISBNX: - case BARCODE_RM4SCC: - case BARCODE_DATAMATRIX: - case BARCODE_EAN14: - case BARCODE_NVE18: - case BARCODE_JAPANPOST: - case BARCODE_KOREAPOST: - case BARCODE_DBAR_STK: - case BARCODE_DBAR_OMNSTK: - case BARCODE_DBAR_EXPSTK: - case BARCODE_PLANET: - case BARCODE_MICROPDF417: - case BARCODE_USPS_IMAIL: - case BARCODE_PLESSEY: - case BARCODE_TELEPEN_NUM: - case BARCODE_ITF14: - case BARCODE_KIX: - case BARCODE_AZTEC: - case BARCODE_DAFT: - case BARCODE_MICROQR: - case BARCODE_HIBC_128: - case BARCODE_HIBC_39: - case BARCODE_HIBC_DM: - case BARCODE_HIBC_QR: - case BARCODE_HIBC_PDF: - case BARCODE_HIBC_MICPDF: - case BARCODE_HIBC_AZTEC: - case BARCODE_HIBC_BLOCKF: - case BARCODE_AZRUNE: - case BARCODE_CODE32: - case BARCODE_EANX_CC: - case BARCODE_GS1_128_CC: - case BARCODE_DBAR_OMN_CC: - case BARCODE_DBAR_LTD_CC: - case BARCODE_DBAR_EXP_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - case BARCODE_DBAR_STK_CC: - case BARCODE_DBAR_OMNSTK_CC: - case BARCODE_DBAR_EXPSTK_CC: - case BARCODE_CHANNEL: - case BARCODE_CODEONE: - case BARCODE_GRIDMATRIX: - case BARCODE_HANXIN: - case BARCODE_DOTCODE: - case BARCODE_CODABLOCKF: - case BARCODE_UPNQR: - case BARCODE_VIN: - case BARCODE_MAILMARK: - case BARCODE_ULTRA: - case BARCODE_RMQR: - case BARCODE_DPD: - result = 1; - break; + if (symbol_id <= 0 || symbol_id > 145) { + return 0; } - return result; + return ids[symbol_id] != 0; } static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, size_t in_length); @@ -1088,13 +1013,13 @@ static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_ break; case 'u': if (in_posn + 6 > *length) { - strcpy(symbol->errtxt, "235: Incomplete unicode escape character in input data"); + strcpy(symbol->errtxt, "209: Incomplete unicode escape character in input data"); return ZINT_ERROR_INVALID_DATA; } unicode = 0; for (i = 0; i < 4; i++) { if (ctoi(input_string[in_posn + i + 2]) == -1) { - strcpy(symbol->errtxt, "236: Corrupt unicode escape character in input data"); + strcpy(symbol->errtxt, "211: Corrupt unicode escape character in input data"); return ZINT_ERROR_INVALID_DATA; } unicode = unicode << 4; @@ -1173,135 +1098,141 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int #endif /* First check the symbology field */ - if (symbol->symbology < 1) { - strcpy(symbol->errtxt, "206: Symbology out of range"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; - } - /* symbol->symbologys 1 to 86 are defined by tbarcode */ - } else if (symbol->symbology == 5) { - symbol->symbology = BARCODE_C25STANDARD; - } else if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) { - symbol->symbology = BARCODE_EANX; - } else if (symbol->symbology == 15) { - symbol->symbology = BARCODE_EANX; - } else if (symbol->symbology == 17) { - symbol->symbology = BARCODE_UPCA; - } else if (symbol->symbology == 19) { - strcpy(symbol->errtxt, "207: Codabar 18 not supported"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return WARN_FAIL_ALL; - } else { - symbol->symbology = BARCODE_CODABAR; - error_number = ZINT_WARN_INVALID_OPTION; - } - } else if (symbol->symbology == 26) { - symbol->symbology = BARCODE_UPCA; - } else if (symbol->symbology == 27) { - strcpy(symbol->errtxt, "208: UPCD1 not supported"); - error_number = ZINT_ERROR_INVALID_OPTION; - } else if (symbol->symbology == 33) { - symbol->symbology = BARCODE_GS1_128; - } else if (symbol->symbology == 36) { - symbol->symbology = BARCODE_UPCA; - } else if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) { - symbol->symbology = BARCODE_POSTNET; - } else if (symbol->symbology == 46) { - symbol->symbology = BARCODE_PLESSEY; - } else if (symbol->symbology == 48) { - symbol->symbology = BARCODE_NVE18; - } else if (symbol->symbology == 54) { - strcpy(symbol->errtxt, "210: General Parcel Code not supported"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; - } - } else if ((symbol->symbology == 59) || (symbol->symbology == 61)) { - symbol->symbology = BARCODE_CODE128; - } else if (symbol->symbology == 62) { - symbol->symbology = BARCODE_CODE93; - } else if ((symbol->symbology == 64) || (symbol->symbology == 65)) { - symbol->symbology = BARCODE_AUSPOST; - } else if (symbol->symbology == 78) { - symbol->symbology = BARCODE_DBAR_OMN; - } else if (symbol->symbology == 83) { - symbol->symbology = BARCODE_PLANET; - } else if (symbol->symbology == 88) { - symbol->symbology = BARCODE_GS1_128; - } else if (symbol->symbology == 91) { - strcpy(symbol->errtxt, "212: Symbology out of range"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; - } - } else if ((symbol->symbology >= 94) && (symbol->symbology <= 95)) { - strcpy(symbol->errtxt, "213: Symbology out of range"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; - } - } else if (symbol->symbology == 100) { - symbol->symbology = BARCODE_HIBC_128; - } else if (symbol->symbology == 101) { - symbol->symbology = BARCODE_HIBC_39; - } else if (symbol->symbology == 103) { - symbol->symbology = BARCODE_HIBC_DM; - } else if (symbol->symbology == 105) { - symbol->symbology = BARCODE_HIBC_QR; - } else if (symbol->symbology == 107) { - symbol->symbology = BARCODE_HIBC_PDF; - } else if (symbol->symbology == 109) { - symbol->symbology = BARCODE_HIBC_MICPDF; - } else if (symbol->symbology == 111) { - symbol->symbology = BARCODE_HIBC_BLOCKF; - } else if ((symbol->symbology == 113) || (symbol->symbology == 114)) { - strcpy(symbol->errtxt, "214: Symbology out of range"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; - } - } else if (symbol->symbology == 115) { - symbol->symbology = BARCODE_DOTCODE; - } else if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) { - if (symbol->symbology != 121) { - strcpy(symbol->errtxt, "215: Symbology out of range"); + if (!ZBarcode_ValidID(symbol->symbology)) { + if (symbol->symbology < 1) { + strcpy(symbol->errtxt, "206: Symbology out of range"); if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + /* symbol->symbologys 1 to 86 are defined by tbarcode */ + } else if (symbol->symbology == 5) { + symbol->symbology = BARCODE_C25STANDARD; + } else if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) { + symbol->symbology = BARCODE_EANX; + } else if (symbol->symbology == 15) { + symbol->symbology = BARCODE_EANX; + } else if (symbol->symbology == 17) { + symbol->symbology = BARCODE_UPCA; + } else if (symbol->symbology == 19) { + strcpy(symbol->errtxt, "207: Codabar 18 not supported"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODABAR; + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if (symbol->symbology == 26) { + symbol->symbology = BARCODE_UPCA; + } else if (symbol->symbology == 27) { + strcpy(symbol->errtxt, "208: UPCD1 not supported"); + error_number = ZINT_ERROR_INVALID_OPTION; + } else if (symbol->symbology == 33) { + symbol->symbology = BARCODE_GS1_128; + } else if (symbol->symbology == 36) { + symbol->symbology = BARCODE_UPCA; + } else if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) { + symbol->symbology = BARCODE_POSTNET; + } else if (symbol->symbology == 46) { + symbol->symbology = BARCODE_PLESSEY; + } else if (symbol->symbology == 48) { + symbol->symbology = BARCODE_NVE18; + } else if (symbol->symbology == 54) { + strcpy(symbol->errtxt, "210: General Parcel Code not supported"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if ((symbol->symbology == 59) || (symbol->symbology == 61)) { + symbol->symbology = BARCODE_CODE128; + } else if (symbol->symbology == 62) { + symbol->symbology = BARCODE_CODE93; + } else if ((symbol->symbology == 64) || (symbol->symbology == 65)) { + symbol->symbology = BARCODE_AUSPOST; + } else if (symbol->symbology == 78) { + symbol->symbology = BARCODE_DBAR_OMN; + } else if (symbol->symbology == 83) { + symbol->symbology = BARCODE_PLANET; + } else if (symbol->symbology == 88) { + symbol->symbology = BARCODE_GS1_128; + } else if (symbol->symbology == 91) { + strcpy(symbol->errtxt, "212: Symbology out of range"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if ((symbol->symbology >= 94) && (symbol->symbology <= 95)) { + strcpy(symbol->errtxt, "213: Symbology out of range"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if (symbol->symbology == 100) { + symbol->symbology = BARCODE_HIBC_128; + } else if (symbol->symbology == 101) { + symbol->symbology = BARCODE_HIBC_39; + } else if (symbol->symbology == 103) { + symbol->symbology = BARCODE_HIBC_DM; + } else if (symbol->symbology == 105) { + symbol->symbology = BARCODE_HIBC_QR; + } else if (symbol->symbology == 107) { + symbol->symbology = BARCODE_HIBC_PDF; + } else if (symbol->symbology == 109) { + symbol->symbology = BARCODE_HIBC_MICPDF; + } else if (symbol->symbology == 111) { + symbol->symbology = BARCODE_HIBC_BLOCKF; + } else if ((symbol->symbology == 113) || (symbol->symbology == 114)) { + strcpy(symbol->errtxt, "214: Symbology out of range"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if (symbol->symbology == 115) { + symbol->symbology = BARCODE_DOTCODE; + } else if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) { + if (symbol->symbology != 121) { + strcpy(symbol->errtxt, "215: Symbology out of range"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else { + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + } + /* Everything from 128 up is Zint-specific */ + } else if (symbol->symbology > 145) { + strcpy(symbol->errtxt, "216: Symbology out of range"); + if (symbol->warn_level == WARN_FAIL_ALL) { + error_number = ZINT_ERROR_INVALID_OPTION; } else { symbol->symbology = BARCODE_CODE128; error_number = ZINT_WARN_INVALID_OPTION; } } - /* Everything from 128 up is Zint-specific */ - } else if (symbol->symbology > 145) { - strcpy(symbol->errtxt, "216: Symbology out of range"); - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZINT_ERROR_INVALID_OPTION; - } else { - symbol->symbology = BARCODE_CODE128; - error_number = ZINT_WARN_INVALID_OPTION; + if (error_number >= ZINT_ERROR) { + error_tag(symbol->errtxt, error_number); + return error_number; } } - if ((!(supports_eci(symbol->symbology))) && (symbol->eci != 0)) { - strcpy(symbol->errtxt, "217: Symbology does not support ECI switching"); - error_number = ZINT_ERROR_INVALID_OPTION; - } - - if ((symbol->eci < 0) || (symbol->eci == 1) || (symbol->eci == 2) || (symbol->eci > 999999)) { - strcpy(symbol->errtxt, "218: Invalid ECI mode"); - error_number = ZINT_ERROR_INVALID_OPTION; + if (symbol->eci != 0) { + if (!(supports_eci(symbol->symbology))) { + strcpy(symbol->errtxt, "217: Symbology does not support ECI switching"); + error_number = ZINT_ERROR_INVALID_OPTION; + } else if ((symbol->eci < 0) || (symbol->eci == 1) || (symbol->eci == 2) || (symbol->eci > 999999)) { + strcpy(symbol->errtxt, "218: Invalid ECI mode"); + error_number = ZINT_ERROR_INVALID_OPTION; + } } if ((symbol->dot_size < 0.01f) || (symbol->dot_size > 20.0f)) { @@ -1316,9 +1247,8 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int if (error_number >= ZINT_ERROR) { error_tag(symbol->errtxt, error_number); return error_number; - } else { - error_buffer = error_number; } + error_buffer = error_number; memcpy(local_source, source, in_length); local_source[in_length] = '\0'; @@ -1524,7 +1454,7 @@ int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle) { case 270: break; default: - strcpy(symbol->errtxt, "228: Invalid rotation angle"); + strcpy(symbol->errtxt, "219: Invalid rotation angle"); error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION); return ZINT_ERROR_INVALID_OPTION; } @@ -1607,7 +1537,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { if (!filename) { strcpy(symbol->errtxt, "239: Filename NULL"); - error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); return ZINT_ERROR_INVALID_DATA; } @@ -1617,8 +1547,8 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { } else { file = fopen(filename, "rb"); if (!file) { - strcpy(symbol->errtxt, "229: Unable to read input file"); - error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION); + sprintf(symbol->errtxt, "229: Unable to read input file (%.30s)", strerror(errno)); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); return ZINT_ERROR_INVALID_DATA; } @@ -1627,14 +1557,14 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { fileLen = ftell(file); fseek(file, 0, SEEK_SET); - if (fileLen > 7900) { + if (fileLen > 7900 && fileLen != LONG_MAX) { /* On many Linux distros ftell() returns LONG_MAX not -1 on error */ /* The largest amount of data that can be encoded is 7827 numeric digits in Han Xin Code */ strcpy(symbol->errtxt, "230: Input file too long"); error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); fclose(file); return ZINT_ERROR_INVALID_DATA; } - if (fileLen <= 0) { + if (fileLen <= 0 || fileLen == LONG_MAX) { strcpy(symbol->errtxt, "235: Input file empty or unseekable"); error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); fclose(file); @@ -1658,7 +1588,8 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { do { n = fread(buffer + nRead, 1, fileLen - nRead, file); if (ferror(file)) { - strcpy(symbol->errtxt, strerror(errno)); + sprintf(symbol->errtxt, "241: Input file read error (%.30s)", strerror(errno)); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); if (strcmp(filename, "-")) { fclose(file); } diff --git a/backend/pcx.c b/backend/pcx.c index 22bd3bdd..a99343ee 100644 --- a/backend/pcx.c +++ b/backend/pcx.c @@ -43,7 +43,7 @@ #include #endif -INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { +INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { int fgred, fggrn, fgblu, bgred, bggrn, bgblu; int row, column, i, colour; int run_count; diff --git a/backend/pdf417.c b/backend/pdf417.c index 60185201..83bfe663 100644 --- a/backend/pdf417.c +++ b/backend/pdf417.c @@ -50,8 +50,14 @@ #include #include "ms_stdint.h" #endif -#include "pdf417.h" +#include #include "common.h" +#include "pdf417.h" + +#define TEX 900 +#define BYT 901 +#define NUM 902 + /* Three figure numbers in comments give the location of command equivalents in the original Visual Basic source code file pdf417.frm @@ -59,14 +65,16 @@ /* text mode processing tables */ -static const char asciix[95] = { +static const char asciix[127] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 8, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 12, 8, 8, 4, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, 8, 8 }; -static const char asciiy[95] = { +static const char asciiy[127] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 15, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4, 5, 6, 24, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, @@ -85,17 +93,16 @@ static const char MicroAutosize[56] = { /* 866 */ -static int quelmode(char codeascii) { - int mode = BYT; - if ((codeascii == '\t') || (codeascii == '\n') || (codeascii == '\r') || ((codeascii >= ' ') && (codeascii <= '~'))) { - mode = TEX; +static int quelmode(unsigned char codeascii) { + if ((codeascii <= '9') && (codeascii >= '0')) { + return NUM; } - if ((codeascii >= '0') && (codeascii <= '9')) { - mode = NUM; + if (codeascii < 127 && asciix[codeascii]) { + return TEX; } /* 876 */ - return mode; + return BYT; } /* 844 */ @@ -230,21 +237,9 @@ static void textprocess(int *chainemc, int *mclength, char chaine[], int start, /* listet will contain the table numbers and the value of each characters */ for (indexlistet = 0; indexlistet < length; indexlistet++) { - char codeascii = chaine[start + indexlistet]; - switch (codeascii) { - case '\t': listet[0][indexlistet] = 12; - listet[1][indexlistet] = 12; - break; - case '\n': listet[0][indexlistet] = 8; - listet[1][indexlistet] = 15; - break; - case 13: listet[0][indexlistet] = 12; - listet[1][indexlistet] = 11; - break; - default: listet[0][indexlistet] = asciix[codeascii - 32]; - listet[1][indexlistet] = asciiy[codeascii - 32]; - break; - } + int codeascii = chaine[start + indexlistet]; + listet[0][indexlistet] = asciix[codeascii]; + listet[1][indexlistet] = asciiy[codeascii]; } /* 570 */ @@ -271,13 +266,11 @@ static void textprocess(int *chainemc, int *mclength, char chaine[], int start, chainet[wnet] = 27; chainet[wnet + 1] = listet[1][j]; wnet += 2; - } - if (listet[0][j] & 8) { /* T_PUN */ + } else if (listet[0][j] & 8) { /* T_PUN (T_PUN and T_UPP not both possible) */ chainet[wnet] = 29; chainet[wnet + 1] = listet[1][j]; wnet += 2; - } - if (!(((listet[0][j] & 1) && (curtable == 2)) || (listet[0][j] & 8))) { + } else { /* No temporary switch available */ flag = FALSE; } @@ -298,24 +291,10 @@ static void textprocess(int *chainemc, int *mclength, char chaine[], int start, } /* Maintain the first if several tables are possible */ - switch (newtable) { - case 3: - case 5: - case 7: - case 9: - case 11: - case 13: - case 15: - newtable = 1; - break; - case 6: - case 10: - case 14: - newtable = 2; - break; - case 12: - newtable = 4; - break; + if (newtable == 7) { + newtable = 1; + } else if (newtable == 12) { + newtable = 4; } /* 619 - select the switch */ @@ -471,9 +450,7 @@ INTERNAL void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], /* 712 */ static void numbprocess(int *chainemc, int *mclength, char chaine[], int start, int length) { int j, loop, dummy[50] = {0}, diviseur, nombre; - char chainemod[50], chainemult[100], temp; - - strcpy(chainemod, ""); + char chainemod[46], chainemult[46]; chainemc[(*mclength)++] = 902; @@ -481,12 +458,12 @@ static void numbprocess(int *chainemc, int *mclength, char chaine[], int start, while (j < length) { int longueur; int dumlength = 0; - strcpy(chainemod, ""); + int p; longueur = length - j; if (longueur > 44) { longueur = 44; } - strcat(chainemod, "1"); + chainemod[0] = '1'; for (loop = 1; loop <= longueur; loop++) { chainemod[loop] = chaine[start + loop + j - 1]; } @@ -495,36 +472,29 @@ static void numbprocess(int *chainemc, int *mclength, char chaine[], int start, diviseur = 900; /* 877 - gosub Modulo */ - strcpy(chainemult, ""); + p = 0; + chainemult[p] = '\0'; nombre = 0; - while (strlen(chainemod) != 0) { + for (loop = 0; chainemod[loop]; loop++) { nombre *= 10; - nombre += ctoi(chainemod[0]); - for (loop = 0; loop < (int)strlen(chainemod); loop++) { - chainemod[loop] = chainemod[loop + 1]; - } + nombre += ctoi(chainemod[loop]); if (nombre < diviseur) { - if (strlen(chainemult) != 0) { - strcat(chainemult, "0"); + if (p) { + chainemult[p++] = '0'; } } else { - temp = (nombre / diviseur) + '0'; - chainemult[strlen(chainemult) + 1] = '\0'; - chainemult[strlen(chainemult)] = temp; + chainemult[p++] = (nombre / diviseur) + '0'; + nombre = nombre % diviseur; } - nombre = nombre % diviseur; } + chainemult[p] = '\0'; diviseur = nombre; /* return to 723 */ - for (loop = dumlength; loop > 0; loop--) { - dummy[loop] = dummy[loop - 1]; - } - dummy[0] = diviseur; - dumlength++; + dummy[dumlength++] = diviseur; strcpy(chainemod, chainemult); - } while (strlen(chainemult) != 0); - for (loop = 0; loop < dumlength; loop++) { + } while (p); + for (loop = dumlength - 1; loop >= 0; loop--) { chainemc[(*mclength)++] = dummy[loop]; } j += longueur; @@ -532,8 +502,8 @@ static void numbprocess(int *chainemc, int *mclength, char chaine[], int start, } /* 366 */ -static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) { - int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520], offset; +static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const int length) { + int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520] = {0}, offset; int total, chainemc[PDF417_MAX_LEN], mclength, c1, c2, c3, dummy[35], calcheight; int liste[2][PDF417_MAX_LEN] = {{0}}; char pattern[580]; @@ -554,13 +524,13 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size /* 463 */ do { liste[1][indexliste] = mode; - while ((liste[1][indexliste] == mode) && (indexchaine < (int)length)) { + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { liste[0][indexliste]++; indexchaine++; mode = quelmode(chaine[indexchaine]); } indexliste++; - } while (indexchaine < (int)length); + } while (indexchaine < length); /* 474 */ pdfsmooth(liste, &indexliste); @@ -592,22 +562,24 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size } if (symbol->eci != 0) { + if (symbol->eci > 811799) { + strcpy(symbol->errtxt, "472: Invalid ECI"); + return ZINT_ERROR_INVALID_OPTION; + } /* Encoding ECI assignment number, according to Table 8 */ if (symbol->eci <= 899) { chainemc[mclength] = 927; /* ECI */ mclength++; chainemc[mclength] = symbol->eci; mclength++; - } - if ((symbol->eci >= 900) && (symbol->eci <= 810899)) { + } else if (symbol->eci <= 810899) { chainemc[mclength] = 926; /* ECI */ mclength++; chainemc[mclength] = (symbol->eci / 900) - 1; mclength++; chainemc[mclength] = symbol->eci % 900; mclength++; - } - if (symbol->eci >= 810900) { + } else { chainemc[mclength] = 925; /* ECI */ mclength++; chainemc[mclength] = symbol->eci - 810900; @@ -615,11 +587,6 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size } } - if (symbol->eci > 811799) { - strcpy(symbol->errtxt, "472: Invalid ECI"); - return ZINT_ERROR_INVALID_OPTION; - } - for (i = 0; i < indexliste; i++) { switch (liste[1][i]) { case TEX: /* 547 - text mode */ @@ -634,6 +601,7 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size } indexchaine = indexchaine + liste[0][i]; } + assert(mclength > 0); /* Suppress clang-analyzer-core.uninitialized.Assign warning */ if (debug) { printf("\nCompressed data stream:\n"); @@ -645,18 +613,16 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size /* 752 - Now take care of the number of CWs per row */ if (symbol->option_1 < 0) { - symbol->option_1 = 6; - if (mclength <= 863) { - symbol->option_1 = 5; - } - if (mclength <= 320) { - symbol->option_1 = 4; - } - if (mclength <= 160) { - symbol->option_1 = 3; - } if (mclength <= 40) { symbol->option_1 = 2; + } else if (mclength <= 160) { + symbol->option_1 = 3; + } else if (mclength <= 320) { + symbol->option_1 = 4; + } else if (mclength <= 863) { + symbol->option_1 = 5; + } else { + symbol->option_1 = 6; } } k = 1; @@ -664,26 +630,25 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size k *= 2; } longueur = mclength; - if (symbol->option_2 > 30) { - symbol->option_2 = 30; - } - if (symbol->option_2 < 1) { - symbol->option_2 =(int)(0.5 + sqrt((longueur + k) / 3.0)); - } - if (((longueur + k) / symbol->option_2) > 90) { - /* stop the symbol from becoming too high */ - symbol->option_2 = symbol->option_2 + 1; - } - if (longueur + k > 928) { /* Enforce maximum codeword limit */ strcpy(symbol->errtxt, "464: Input string too long"); return ZINT_ERROR_TOO_LONG; } + if (symbol->option_2 > 30) { + symbol->option_2 = 30; + } else if (symbol->option_2 < 1) { + symbol->option_2 = (int) (0.5 + sqrt((longueur + k) / 3.0)); + } if (((longueur + k) / symbol->option_2) > 90) { - strcpy(symbol->errtxt, "465: Data too long for specified number of columns"); - return ZINT_ERROR_TOO_LONG; + /* stop the symbol from becoming too high */ + symbol->option_2 = symbol->option_2 + 1; + + if (((longueur + k) / symbol->option_2) > 90) { + strcpy(symbol->errtxt, "465: Data too long for specified number of columns"); + return ZINT_ERROR_TOO_LONG; + } } /* 781 - Padding calculation */ @@ -732,15 +697,12 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size } longueur = mclength; - for (loop = 0; loop < 520; loop++) { - mccorrection[loop] = 0; - } for (i = 0; i < longueur; i++) { total = (chainemc[i] + mccorrection[k - 1]) % 929; for (j = k - 1; j > 0; j--) { mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; } - mccorrection[0] = (929 - (total * coefrs[offset + j]) % 929) % 929; + mccorrection[0] = (929 - (total * coefrs[offset]) % 929) % 929; } /* we add these codes to the string */ @@ -762,6 +724,7 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size #endif symbol->rows = mclength / symbol->option_2; + assert(symbol->rows > 0); /* Suppress clang-analyzer-core.DivideZero warning */ /* 818 - The CW string is finished */ c1 = (symbol->rows - 1) / 3; @@ -770,6 +733,7 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size /* we now encode each row */ for (i = 0; i < symbol->rows; i++) { + int p; for (j = 0; j < symbol->option_2; j++) { dummy[j + 1] = chainemc[i * symbol->option_2 + j]; } @@ -791,23 +755,23 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size offset = 1858; /* cluster(6) */ break; } - strcpy(pattern, ""); - bin_append(0x1FEA8, 17, pattern); /* Row start */ + p = bin_append_posn(0x1FEA8, 17, pattern, 0); /* Row start */ for (j = 0; j <= symbol->option_2; j++) { - bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); - strcat(pattern, "0"); + p = bin_append_posn(pdf_bitpattern[offset + dummy[j]], 16, pattern, p); + pattern[p++] = '0'; } if (symbol->symbology != BARCODE_PDF417COMP) { - bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); - strcat(pattern, "0"); - bin_append(0x3FA29, 18, pattern); /* Row Stop */ + p = bin_append_posn(pdf_bitpattern[offset + dummy[j]], 16, pattern, p); + pattern[p++] = '0'; + p = bin_append_posn(0x3FA29, 18, pattern, p); /* Row Stop */ } else { - strcat(pattern, "1"); /* Compact PDF417 Stop pattern */ + pattern[p++] = '1'; /* Compact PDF417 Stop pattern */ } + pattern[p] = '\0'; - for (loop = 0; loop < (int)strlen(pattern); loop++) { + for (loop = 0; loop < p; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); } @@ -831,7 +795,7 @@ static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size } /* 345 */ -INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length) { +INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length) { int codeerr, error_number; error_number = 0; @@ -868,8 +832,8 @@ INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const } /* like PDF417 only much smaller! */ -INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) { - int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50], offset; +INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) { + int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50] = {0}, offset; int total, chainemc[PDF417_MAX_LEN], mclength, dummy[5], codeerr; int liste[2][PDF417_MAX_LEN] = {{0}}; char pattern[580]; @@ -894,13 +858,13 @@ INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], co /* 463 */ do { liste[1][indexliste] = mode; - while ((liste[1][indexliste] == mode) && (indexchaine < (int)length)) { + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { liste[0][indexliste]++; indexchaine++; mode = quelmode(chaine[indexchaine]); } indexliste++; - } while (indexchaine < (int)length); + } while (indexchaine < length); /* 474 */ pdfsmooth(liste, &indexliste); @@ -1181,9 +1145,6 @@ INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], co /* Reed-Solomon error correction */ longueur = mclength; - for (loop = 0; loop < 50; loop++) { - mccorrection[loop] = 0; - } for (i = 0; i < longueur; i++) { total = (chainemc[i] + mccorrection[k - 1]) % 929; for (j = k - 1; j >= 0; j--) { diff --git a/backend/pdf417.h b/backend/pdf417.h index d126c2e3..29ad5a41 100644 --- a/backend/pdf417.h +++ b/backend/pdf417.h @@ -34,11 +34,8 @@ /* this file contains the character table, the pre-calculated coefficients and the codeword patterns taken from lines 416 to 454 of pdf417.frm */ -#define TRUE 1 -#define FALSE 0 -#define TEX 900 -#define BYT 901 -#define NUM 902 +#ifndef __PDF417_H +#define __PDF417_H /* PDF417 error correction coefficients from Grand Zebu */ static const unsigned short int coefrs[1022] = { @@ -511,4 +508,6 @@ static const unsigned short int rap_centre[52] = { 0x2DC, 0x2DE }; -void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int debug); +INTERNAL void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int debug); + +#endif /* __PDF417_H */ diff --git a/backend/png.c b/backend/png.c index 6a826e4a..bfe1a9b8 100644 --- a/backend/png.c +++ b/backend/png.c @@ -72,14 +72,32 @@ static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) { longjmp(graphic->jmpbuf, 1); } -INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { +INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { struct mainprog_info_type wpng_info; struct mainprog_info_type *graphic; png_structp png_ptr; png_infop info_ptr; - int i, row, column; - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; - int fgalpha, bgalpha, use_alpha; + int row, column; + unsigned char fg[4], bg[4]; + unsigned char white[4] = { 0xff, 0xff, 0xff, 0xff }; + unsigned char cyan[4] = { 0, 0xff, 0xff, 0xff }; + unsigned char blue[4] = { 0, 0, 0xff, 0xff }; + unsigned char magenta[4] = { 0xff, 0, 0xff, 0xff }; + unsigned char red[4] = { 0xff, 0, 0, 0xff }; + unsigned char yellow[4] = { 0xff, 0xff, 0, 0xff }; + unsigned char green[4] = { 0, 0xff, 0, 0xff }; + unsigned char black[4] = { 0, 0, 0, 0xff }; + unsigned char *map[91] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00-0F */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10-1F */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x20-2F */ + bg, fg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0-9 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* :;<=>?@ */ + NULL, blue, cyan, NULL, NULL, NULL, green, NULL, NULL, NULL, black, NULL, magenta, /* A-M */ + NULL, NULL, NULL, NULL, red, NULL, NULL, NULL, NULL, white, NULL, yellow, NULL /* N-Z */ + }; + int use_alpha, incr; + unsigned char *image_data; #ifndef _MSC_VER unsigned char outdata[symbol->bitmap_width * 4]; @@ -92,27 +110,28 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { graphic->width = symbol->bitmap_width; graphic->height = symbol->bitmap_height; - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + fg[0] = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fg[1] = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fg[2] = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bg[0] = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bg[1] = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bg[2] = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); use_alpha = 0; if (strlen(symbol->fgcolour) > 6) { - fgalpha = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); - if (fgalpha != 0xff) use_alpha = 1; + fg[3] = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); + white[3] = cyan[3] = blue[3] = magenta[3] = red[3] = yellow[3] = green[3] = black[3] = fg[3]; + if (fg[3] != 0xff) use_alpha = 1; } else { - fgalpha = 0xff; + fg[3] = 0xff; } if (strlen(symbol->bgcolour) > 6) { - bgalpha = (16 * ctoi(symbol->bgcolour[6])) + ctoi(symbol->bgcolour[7]); - if (bgalpha != 0xff) use_alpha = 1; + bg[3] = (16 * ctoi(symbol->bgcolour[6])) + ctoi(symbol->bgcolour[7]); + if (bg[3] != 0xff) use_alpha = 1; } else { - bgalpha = 0xff; + bg[3] = 0xff; } /* Open output file in binary mode */ @@ -175,78 +194,15 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { png_set_packing(png_ptr); /* Pixel Plotting */ + incr = use_alpha ? 4 : 3; for (row = 0; row < symbol->bitmap_height; row++) { - unsigned char *image_data; - for (column = 0; column < symbol->bitmap_width; column++) { - i = column * 3; - if (use_alpha) i += column; - switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) { - case 'W': // White - outdata[i] = 255; - outdata[i + 1] = 255; - outdata[i + 2] = 255; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'C': // Cyan - outdata[i] = 0; - outdata[i + 1] = 255; - outdata[i + 2] = 255; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'B': // Blue - outdata[i] = 0; - outdata[i + 1] = 0; - outdata[i + 2] = 255; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'M': // Magenta - outdata[i] = 255; - outdata[i + 1] = 0; - outdata[i + 2] = 255; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'R': // Red - outdata[i] = 255; - outdata[i + 1] = 0; - outdata[i + 2] = 0; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'Y': // Yellow - outdata[i] = 255; - outdata[i + 1] = 255; - outdata[i + 2] = 0; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'G': // Green - outdata[i] = 0; - outdata[i + 1] = 255; - outdata[i + 2] = 0; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case 'K': // Black - outdata[i] = 0; - outdata[i + 1] = 0; - outdata[i + 2] = 0; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - case '1': - outdata[i] = fgred; - outdata[i + 1] = fggrn; - outdata[i + 2] = fgblu; - if (use_alpha) outdata[i + 3] = fgalpha; - break; - default: - outdata[i] = bgred; - outdata[i + 1] = bggrn; - outdata[i + 2] = bgblu; - if (use_alpha) outdata[i + 3] = bgalpha; - break; - - } + int p = symbol->bitmap_width * row; + image_data = outdata; + for (column = 0; column < symbol->bitmap_width; column++, p++, image_data += incr) { + memcpy(image_data, map[pixelbuf[p]], incr); } /* write row contents to file */ - image_data = outdata; - png_write_row(png_ptr, image_data); + png_write_row(png_ptr, outdata); } /* End the file */ diff --git a/backend/raster.c b/backend/raster.c index 33de24d9..94463db9 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -52,21 +52,46 @@ #define UPCEAN_TEXT 1 #ifndef NO_PNG -INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); #endif /* NO_PNG */ -INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); -INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); -INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); -INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); +INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); +INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); +INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); static const char ultra_colour[] = "0CBMRYGKW"; -static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { +static int buffer_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { /* Place pixelbuffer into symbol */ - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; int fgalpha, bgalpha; - int row, column, i; + unsigned char fg[3], bg[3]; + unsigned char white[3] = { 0xff, 0xff, 0xff }; + unsigned char cyan[3] = { 0, 0xff, 0xff }; + unsigned char blue[3] = { 0, 0, 0xff }; + unsigned char magenta[3] = { 0xff, 0, 0xff }; + unsigned char red[3] = { 0xff, 0, 0 }; + unsigned char yellow[3] = { 0xff, 0xff, 0 }; + unsigned char green[3] = { 0, 0xff, 0 }; + unsigned char black[3] = { 0, 0, 0 }; + unsigned char *map[91] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00-0F */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10-1F */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x20-2F */ + bg, fg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0-9 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* :;<=>?@ */ + NULL, blue, cyan, NULL, NULL, NULL, green, NULL, NULL, NULL, black, NULL, magenta, /* A-M */ + NULL, NULL, NULL, NULL, red, NULL, NULL, NULL, NULL, white, NULL, yellow, NULL /* N-Z */ + }; + int row, column, p; int plot_alpha = 0; + unsigned char *bitmap; + + fg[0] = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fg[1] = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fg[2] = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bg[0] = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bg[1] = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bg[2] = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); if (strlen(symbol->fgcolour) > 6) { fgalpha = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); @@ -92,90 +117,32 @@ static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { symbol->alphamap = NULL; } - symbol->bitmap = (unsigned char *) malloc(symbol->bitmap_width * symbol->bitmap_height * 3); + symbol->bitmap = (unsigned char *) malloc((size_t) symbol->bitmap_width * symbol->bitmap_height * 3); if (symbol->bitmap == NULL) { strcpy(symbol->errtxt, "661: Insufficient memory for bitmap buffer"); return ZINT_ERROR_MEMORY; } + if (plot_alpha) { - symbol->alphamap = (unsigned char *) malloc(symbol->bitmap_width * symbol->bitmap_height); + symbol->alphamap = (unsigned char *) malloc((size_t) symbol->bitmap_width * symbol->bitmap_height); if (symbol->alphamap == NULL) { strcpy(symbol->errtxt, "662: Insufficient memory for alphamap buffer"); return ZINT_ERROR_MEMORY; } - } - - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - - for (row = 0; row < symbol->bitmap_height; row++) { - for (column = 0; column < symbol->bitmap_width; column++) { - i = ((row * symbol->bitmap_width) + column) * 3; - switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) { - case 'W': // White - symbol->bitmap[i] = 255; - symbol->bitmap[i + 1] = 255; - symbol->bitmap[i + 2] = 255; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'C': // Cyan - symbol->bitmap[i] = 0; - symbol->bitmap[i + 1] = 255; - symbol->bitmap[i + 2] = 255; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'B': // Blue - symbol->bitmap[i] = 0; - symbol->bitmap[i + 1] = 0; - symbol->bitmap[i + 2] = 255; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'M': // Magenta - symbol->bitmap[i] = 255; - symbol->bitmap[i + 1] = 0; - symbol->bitmap[i + 2] = 255; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'R': // Red - symbol->bitmap[i] = 255; - symbol->bitmap[i + 1] = 0; - symbol->bitmap[i + 2] = 0; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'Y': // Yellow - symbol->bitmap[i] = 255; - symbol->bitmap[i + 1] = 255; - symbol->bitmap[i + 2] = 0; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'G': // Green - symbol->bitmap[i] = 0; - symbol->bitmap[i + 1] = 255; - symbol->bitmap[i + 2] = 0; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case 'K': // Black - symbol->bitmap[i] = 0; - symbol->bitmap[i + 1] = 0; - symbol->bitmap[i + 2] = 0; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - case DEFAULT_INK: - symbol->bitmap[i] = fgred; - symbol->bitmap[i + 1] = fggrn; - symbol->bitmap[i + 2] = fgblu; - if (plot_alpha) symbol->alphamap[i / 3] = fgalpha; - break; - default: // DEFAULT_PAPER - symbol->bitmap[i] = bgred; - symbol->bitmap[i + 1] = bggrn; - symbol->bitmap[i + 2] = bgblu; - if (plot_alpha) symbol->alphamap[i / 3] = bgalpha; - break; + for (row = 0; row < symbol->bitmap_height; row++) { + p = row * symbol->bitmap_width; + bitmap = symbol->bitmap + p * 3; + for (column = 0; column < symbol->bitmap_width; column++, p++, bitmap += 3) { + memcpy(bitmap, map[pixelbuf[p]], 3); + symbol->alphamap[p] = pixelbuf[p] == DEFAULT_PAPER ? bgalpha : fgalpha; + } + } + } else { + for (row = 0; row < symbol->bitmap_height; row++) { + p = row * symbol->bitmap_width; + bitmap = symbol->bitmap + p * 3; + for (column = 0; column < symbol->bitmap_width; column++, p++, bitmap += 3) { + memcpy(bitmap, map[pixelbuf[p]], 3); } } } @@ -183,12 +150,13 @@ static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { return 0; } -static int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int file_type) { +static int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, unsigned char *pixelbuf, int rotate_angle, int file_type) { int error_number; int row, column; - char *rotated_pixbuf = pixelbuf; + unsigned char *rotated_pixbuf = pixelbuf; + assert(rotate_angle == 0 || rotate_angle == 90 || rotate_angle == 180 || rotate_angle == 270); /* Suppress clang-analyzer-core.UndefinedBinaryOperatorResult warning */ switch (rotate_angle) { case 0: case 180: @@ -203,7 +171,7 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, int image_heigh } if (rotate_angle) { - if (!(rotated_pixbuf = (char *) malloc(image_width * image_height))) { + if (!(rotated_pixbuf = (unsigned char *) malloc((size_t) image_width * image_height))) { strcpy(symbol->errtxt, "650: Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } @@ -251,7 +219,7 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, int image_heigh free(symbol->alphamap); symbol->alphamap = NULL; } - symbol->bitmap = (unsigned char *) rotated_pixbuf; + symbol->bitmap = rotated_pixbuf; rotate_angle = 0; /* Suppress freeing buffer if rotated */ error_number = 0; } else { @@ -288,7 +256,7 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, int image_heigh return error_number; } -static void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height, char fill) { +static void draw_bar(unsigned char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height, char fill) { /* Draw a rectangle */ int i, j, png_ypos; @@ -303,7 +271,7 @@ static void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int } } -static void draw_circle(char *pixelbuf, int image_width, int image_height, int x0, int y0, float radius, char fill) { +static void draw_circle(unsigned char *pixelbuf, int image_width, int image_height, int x0, int y0, float radius, char fill) { int x, y; int radius_i = (int) radius; @@ -319,7 +287,7 @@ static void draw_circle(char *pixelbuf, int image_width, int image_height, int x } } -static void draw_bullseye(char *pixelbuf, int image_width, int image_height, int xoffset, int yoffset, int scaler) { +static void draw_bullseye(unsigned char *pixelbuf, int image_width, int image_height, int xoffset, int yoffset, int scaler) { /* Central bullseye in Maxicode symbols */ float x = 14.5f * scaler; float y = 15.0f * scaler; @@ -336,7 +304,7 @@ static void draw_bullseye(char *pixelbuf, int image_width, int image_height, int draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (0.602f * scaler) + 1.0f, DEFAULT_PAPER); } -static void draw_hexagon(char *pixelbuf, int image_width, char *scaled_hexagon, int hexagon_size, int xposn, int yposn) { +static void draw_hexagon(unsigned char *pixelbuf, int image_width, unsigned char *scaled_hexagon, int hexagon_size, int xposn, int yposn) { /* Put a hexagon into the pixel buffer */ int i, j; @@ -349,7 +317,7 @@ static void draw_hexagon(char *pixelbuf, int image_width, char *scaled_hexagon, } } -static void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int textflags, int image_width, int image_height, int si) { +static void draw_letter(unsigned char *pixelbuf, unsigned char letter, int xposn, int yposn, int textflags, int image_width, int image_height, int si) { /* Put a letter into a position */ int skip; @@ -381,7 +349,7 @@ static void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int ypo int font_y; int half_si = si / 2; int odd_si = si & 1; - char *linePtr, *maxPtr; + unsigned char *linePtr, *maxPtr; int x_start = 0; if (letter > 127) { @@ -432,7 +400,7 @@ static void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int ypo linePtr = pixelbuf + (yposn * image_width) + xposn; for (y = 0; y < max_y; y++) { int x_si, y_si; - char *pixelPtr = linePtr; /* Avoid warning */ + unsigned char *pixelPtr = linePtr; /* Avoid warning */ for (y_si = 0; y_si < half_si; y_si++) { int extra_dot = 0; pixelPtr = linePtr; @@ -470,7 +438,7 @@ static void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int ypo } /* Plot a string into the pixel buffer */ -static void draw_string(char *pixbuf, unsigned char input_string[], int xposn, int yposn, int textflags, int image_width, int image_height, int si) { +static void draw_string(unsigned char *pixbuf, unsigned char input_string[], int xposn, int yposn, int textflags, int image_width, int image_height, int si) { int i, string_length, string_left_hand, letter_width, letter_gap; int half_si = si / 2, odd_si = si & 1, x_incr; @@ -507,7 +475,7 @@ static void draw_string(char *pixbuf, unsigned char input_string[], int xposn, i } } -static void plot_hexline(char *scaled_hexagon, int hexagon_size, float start_x, float start_y, float end_x, float end_y) { +static void plot_hexline(unsigned char *scaled_hexagon, int hexagon_size, float start_x, float start_y, float end_x, float end_y) { /* Draw a straight line from start to end */ int i; float inc_x, inc_y; @@ -524,7 +492,7 @@ static void plot_hexline(char *scaled_hexagon, int hexagon_size, float start_x, } } -static void plot_hexagon(char *scaled_hexagon, int hexagon_size) { +static void plot_hexagon(unsigned char *scaled_hexagon, int hexagon_size) { /* Create a hexagon shape and fill it */ int line, i; @@ -584,11 +552,11 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, in /* Plot a MaxiCode symbol with hexagons and bullseye */ int row, column, xposn; int image_height, image_width; - char *pixelbuf; + unsigned char *pixelbuf; int error_number; int xoffset, yoffset, roffset, boffset; float scaler = symbol->scale; - char *scaled_hexagon; + unsigned char *scaled_hexagon; int hexagon_size; if (scaler < 0.5f) { @@ -597,23 +565,23 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, in output_set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset); - image_width = ceil((300 + 2 * (xoffset + roffset)) * scaler); - image_height = ceil((300 + 2 * (yoffset + boffset)) * scaler); + image_width = ceil((double) (300 + 2 * (xoffset + roffset)) * scaler); + image_height = ceil((double) (300 + 2 * (yoffset + boffset)) * scaler); - if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) { strcpy(symbol->errtxt, "655: Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } - memset(pixelbuf, DEFAULT_PAPER, image_width * image_height); + memset(pixelbuf, DEFAULT_PAPER, (size_t) image_width * image_height); hexagon_size = ceil(scaler * 10); - if (!(scaled_hexagon = (char *) malloc(hexagon_size * hexagon_size))) { + if (!(scaled_hexagon = (unsigned char *) malloc((size_t) hexagon_size * hexagon_size))) { strcpy(symbol->errtxt, "656: Insufficient memory for pixel buffer"); free(pixelbuf); return ZINT_ERROR_ENCODING_PROBLEM; } - memset(scaled_hexagon, DEFAULT_PAPER, hexagon_size * hexagon_size); + memset(scaled_hexagon, DEFAULT_PAPER, (size_t) hexagon_size * hexagon_size); plot_hexagon(scaled_hexagon, hexagon_size); @@ -663,7 +631,7 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, in static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int file_type) { float scaler = 2 * symbol->scale; - char *scaled_pixelbuf; + unsigned char *scaled_pixelbuf; int r, i; int scale_width, scale_height; int error_number = 0; @@ -697,11 +665,11 @@ static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int f scale_height = (symbol->height + yoffset + boffset) * scaler + dot_overspill_scaled; /* Apply scale options by creating another pixel buffer */ - if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) { strcpy(symbol->errtxt, "657: Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } - memset(scaled_pixelbuf, DEFAULT_PAPER, scale_width * scale_height); + memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height); /* Plot the body of the symbol to the pixel buffer */ dotradius_scaled = (symbol->dot_size * scaler) / 2.0f; @@ -771,12 +739,12 @@ static void to_iso8859_1(const unsigned char source[], unsigned char preprocesse static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int file_type) { int error_number; - int large_bar_height; + float large_bar_height; int textdone = 0; int main_width; int comp_offset = 0; unsigned char addon[6]; - int addon_gap; + int addon_gap = 0; float addon_text_posn = 0.0f; int xoffset, yoffset, roffset, boffset; int textoffset; @@ -794,15 +762,14 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int int textflags = 0; int guardoffset = 0; int image_width, image_height; - char *pixelbuf; + unsigned char *pixelbuf; int next_yposn; int latch; - int block_width; float scaler = symbol->scale; int si; int half_int_scaling; int scale_width, scale_height; - char *scaled_pixelbuf; + unsigned char *scaled_pixelbuf; int horiz, vert; /* Ignore scaling < 0.5 for raster as would drop modules */ @@ -856,11 +823,11 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int image_width = (symbol->width + xoffset + roffset) * si; image_height = (symbol->height + textoffset + yoffset + boffset) * si; - if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) { strcpy(symbol->errtxt, "658: Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } - memset(pixelbuf, DEFAULT_PAPER, image_width * image_height); + memset(pixelbuf, DEFAULT_PAPER, (size_t) image_width * image_height); default_text_posn = image_height - (textoffset - text_gap) * si; @@ -873,50 +840,67 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int int plot_yposn; float plot_height; int this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ - int module_fill; row_posn += row_height; plot_yposn = next_yposn; row_height = symbol->row_height[this_row] ? symbol->row_height[this_row] : large_bar_height; next_yposn = (int) (row_posn + row_height); plot_height = next_yposn - plot_yposn; + plot_yposn *= si; + plot_height *= si; + i = 0; - do { - module_fill = module_is_set(symbol, this_row, i); - block_width = 0; + if (symbol->symbology == BARCODE_ULTRA) { do { - block_width++; - } while ((i + block_width < symbol->width) && module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + int module_fill = module_colour_is_set(symbol, this_row, i); + int block_width = 0; + do { + block_width++; + } while ((i + block_width < symbol->width) && module_colour_is_set(symbol, this_row, i + block_width) == module_fill); - if ((addon_latch == 0) && (r == 0) && (i > main_width)) { - plot_height = row_height - (text_height + text_gap) + 5.0f; - plot_yposn = row_posn - 5.0f; - if (plot_yposn < 0.0f) { - plot_yposn = 0.0f; + if (module_fill) { + /* a colour block */ + draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn, plot_height, image_width, image_height, ultra_colour[module_fill]); } - if (upceanflag == 12 || upceanflag == 6) { /* UPC-A/E add-ons don't descend */ - plot_height -= 5.0f; - plot_yposn += 5.0f; - } - if (plot_height < 0.5f) { - plot_height = 0.5f; - } - /* Need to invert composite position */ - addon_text_posn = is_composite(symbol->symbology) ? image_height - (plot_yposn + plot_height + text_height + text_gap) * si : yoffset * si; - addon_latch = 1; - } - if (module_fill) { - /* a bar */ - if (symbol->symbology == BARCODE_ULTRA) { - draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn * si, plot_height * si, image_width, image_height, ultra_colour[module_fill]); - } else { - draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn * si, plot_height * si, image_width, image_height, DEFAULT_INK); - } - } - i += block_width; + i += block_width; - } while (i < symbol->width); + } while (i < symbol->width); + } else { + do { + int module_fill = module_is_set(symbol, this_row, i); + int block_width = 0; + do { + block_width++; + } while ((i + block_width < symbol->width) && module_is_set(symbol, this_row, i + block_width) == module_fill); + + if (upceanflag && (addon_latch == 0) && (r == 0) && (i > main_width)) { + plot_height = row_height - (text_height + text_gap) + 5.0f; + plot_yposn = row_posn - 5.0f; + if (plot_yposn < 0.0f) { + plot_yposn = 0.0f; + } + if (upceanflag == 12 || upceanflag == 6) { /* UPC-A/E add-ons don't descend */ + plot_height -= 5.0f; + plot_yposn += 5.0f; + } + if (plot_height < 0.5f) { + plot_height = 0.5f; + } + /* Need to invert composite position */ + addon_text_posn = is_composite(symbol->symbology) ? image_height - (plot_yposn + plot_height + text_height + text_gap) * si : yoffset * si; + plot_yposn *= si; + plot_height *= si; + addon_latch = 1; + } + if (module_fill) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset) * si, block_width * si, plot_yposn, plot_height, image_width, image_height, DEFAULT_INK); + } + i += block_width; + + } while (i < symbol->width); + } } xoffset += comp_offset; @@ -944,10 +928,11 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int i = 0 + comp_offset; do { - block_width = 0; + int module_fill = module_is_set(symbol, symbol->rows - 1, i); + int block_width = 0; do { block_width++; - } while ((i + block_width < symbol->width) && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + } while ((i + block_width < symbol->width) && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_fill); if (latch == 1) { /* a bar */ draw_bar(pixelbuf, (i + xoffset - comp_offset) * si, block_width * si, guardoffset * si, 5 * si, image_width, image_height, DEFAULT_INK); @@ -963,10 +948,11 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int latch = 1; i = 85 + comp_offset; do { - block_width = 0; + int module_fill = module_is_set(symbol, symbol->rows - 1, i); + int block_width = 0; do { block_width++; - } while ((i + block_width < symbol->width) && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + } while ((i + block_width < symbol->width) && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_fill); if (latch == 1) { /* a bar */ draw_bar(pixelbuf, (i + xoffset - comp_offset) * si, block_width * si, guardoffset * si, 5 * si, image_width, image_height, DEFAULT_INK); @@ -1140,12 +1126,12 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int scale_height = image_height * scaler; /* Apply scale options by creating another pixel buffer */ - if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) { free(pixelbuf); strcpy(symbol->errtxt, "659: Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } - memset(scaled_pixelbuf, DEFAULT_PAPER, scale_width * scale_height); + memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height); for (vert = 0; vert < scale_height; vert++) { int vert_row = vert * scale_width; diff --git a/backend/tests/data/png/pdf417_bgalpha.png b/backend/tests/data/png/pdf417_bgalpha.png new file mode 100644 index 00000000..190cee95 Binary files /dev/null and b/backend/tests/data/png/pdf417_bgalpha.png differ diff --git a/backend/tests/data/png/pdf417_fgalpha.png b/backend/tests/data/png/pdf417_fgalpha.png new file mode 100644 index 00000000..aa1ebed1 Binary files /dev/null and b/backend/tests/data/png/pdf417_fgalpha.png differ diff --git a/backend/tests/data/png/ultra_alpha.png b/backend/tests/data/png/ultra_alpha.png new file mode 100644 index 00000000..8fbefaf2 Binary files /dev/null and b/backend/tests/data/png/ultra_alpha.png differ diff --git a/backend/tests/test_bmp.c b/backend/tests/test_bmp.c index 502dc2d1..046cacde 100644 --- a/backend/tests/test_bmp.c +++ b/backend/tests/test_bmp.c @@ -32,7 +32,7 @@ #include "testcommon.h" #include -extern int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); static void test_pixel_plot(int index, int debug) { @@ -94,7 +94,7 @@ static void test_pixel_plot(int index, int debug) { symbol->bitmap = (unsigned char *) data_buf; - ret = bmp_pixel_plot(symbol, data_buf); + ret = bmp_pixel_plot(symbol, (unsigned char *) data_buf); assert_zero(ret, "i:%d bmp_pixel_plot ret %d != 0 (%s)\n", i, ret, symbol->errtxt); ret = testUtilVerifyIdentify(symbol->outfile, debug); diff --git a/backend/tests/test_gif.c b/backend/tests/test_gif.c index c3d4f654..3cd1a903 100644 --- a/backend/tests/test_gif.c +++ b/backend/tests/test_gif.c @@ -31,7 +31,7 @@ #include "testcommon.h" -extern int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); static void test_pixel_plot(int index, int debug) { @@ -93,7 +93,7 @@ static void test_pixel_plot(int index, int debug) { symbol->bitmap = (unsigned char *) data_buf; - ret = gif_pixel_plot(symbol, data_buf); + ret = gif_pixel_plot(symbol, (unsigned char *) data_buf); assert_zero(ret, "i:%d gif_pixel_plot ret %d != 0 (%s)\n", i, ret, symbol->errtxt); ret = testUtilVerifyIdentify(symbol->outfile, debug); diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 144e06fc..976ad68c 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -46,22 +46,30 @@ static void test_checks(int index, int debug) { int input_mode; int eci; float dot_size; + int warn_level; int ret; char *expected; }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, "1234", -1, -1, 3, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching" }, - /* 1*/ { BARCODE_CODE128, "1234", -1, -1, 0, -1, 0, "" }, - /* 2*/ { BARCODE_QRCODE, "1234", -1, -1, 3, -1, 0, "" }, - /* 3*/ { BARCODE_QRCODE, "1234", -1, -1, 999999 + 1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI mode" }, - /* 4*/ { BARCODE_CODE128, "1234", -1, -1, -1, 20.1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size" }, - /* 5*/ { BARCODE_CODE128, "1234", -1, GS1_MODE, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 220: Selected symbology does not support GS1 mode" }, - /* 6*/ { BARCODE_GS1_128, "[21]12\0004", 8, GS1_MODE, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 262: NUL characters not permitted in GS1 mode" }, - /* 7*/ { BARCODE_GS1_128, "[21]12é4", -1, GS1_MODE, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, - /* 8*/ { BARCODE_GS1_128, "[21]12\0074", -1, GS1_MODE, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 251: Control characters are not supported by GS1" }, - /* 9*/ { BARCODE_GS1_128, "[21]1234", -1, GS1_MODE, -1, -1, 0, "" }, + /* 0*/ { BARCODE_CODE128, "1234", -1, -1, 3, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching" }, + /* 1*/ { BARCODE_CODE128, "1234", -1, -1, 0, -1, -1, 0, "" }, + /* 2*/ { BARCODE_QRCODE, "1234", -1, -1, 3, -1, -1, 0, "" }, + /* 3*/ { BARCODE_QRCODE, "1234", -1, -1, 999999 + 1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI mode" }, + /* 4*/ { BARCODE_CODE128, "1234", -1, -1, -1, 20.1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size" }, + /* 5*/ { BARCODE_CODE128, "1234", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 220: Selected symbology does not support GS1 mode" }, + /* 6*/ { BARCODE_GS1_128, "[21]12\0004", 8, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 262: NUL characters not permitted in GS1 mode" }, + /* 7*/ { BARCODE_GS1_128, "[21]12é4", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, + /* 8*/ { BARCODE_GS1_128, "[21]12\0074", -1, GS1_MODE, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 251: Control characters are not supported by GS1" }, + /* 9*/ { BARCODE_GS1_128, "[21]1234", -1, GS1_MODE, -1, -1, -1, 0, "" }, + /* 10*/ { 0, "1", -1, -1, -1, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range" }, + /* 11*/ { 0, "1", -1, -1, -1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range" }, + /* 12*/ { 0, "1", -1, -1, 1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching" }, // Not supporting beats invalid ECI + /* 13*/ { 0, "1", -1, -1, 1, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range" }, + /* 14*/ { 0, "1", -1, -1, -1, 0.009, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size" }, + /* 15*/ { 0, "1", -1, -1, -1, 0.009, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range" }, + /* 16*/ { 0, "1", -1, -1, 1, 0.009, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Invalid dot size" }, // Invalid dot size beats invalid ECI }; int data_size = sizeof(data) / sizeof(struct item); @@ -82,6 +90,9 @@ static void test_checks(int index, int debug) { if (data[i].dot_size != -1) { symbol->dot_size = data[i].dot_size; } + if (data[i].warn_level != -1) { + symbol->warn_level = data[i].warn_level; + } symbol->debug |= debug; int length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length; @@ -384,6 +395,29 @@ static void test_bad_args(void) { testFinish(); } +static void test_valid_id(void) { + + testStart(""); + + int ret; + const char *name; + + for (int symbol_id = -1; symbol_id < 160; symbol_id++) { + ret = ZBarcode_ValidID(symbol_id); + name = testUtilBarcodeName(symbol_id); + assert_nonnull(name, "testUtilBarcodeName(%d) NULL\n", symbol_id); + if (ret) { + assert_equal(ret, 1, "ZBarcode_Valid(%d) != 1\n", symbol_id); + assert_nonzero(*name != '\0', "testUtilBarcodeName(%d) empty when ZBarcode_Valid() true\n", symbol_id); + } else { + assert_zero(ret, "ZBarcode_Valid(%d) != 0\n", symbol_id); + assert_zero(*name, "testUtilBarcodeName(%d) non-empty when ZBarcode_Valid() false\n", symbol_id); + } + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ @@ -394,6 +428,7 @@ int main(int argc, char *argv[]) { { "test_encode_file_zero_length", test_encode_file_zero_length, 0, 0, 0 }, { "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 }, { "test_bad_args", test_bad_args, 0, 0, 0 }, + { "test_valid_id", test_valid_id, 0, 0, 0 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_pdf417.c b/backend/tests/test_pdf417.c index af2a1b5e..be18a12b 100644 --- a/backend/tests/test_pdf417.c +++ b/backend/tests/test_pdf417.c @@ -213,6 +213,8 @@ static void test_input(int index, int generate, int debug) { /* 22*/ { BARCODE_MICROPDF417, UNICODE_MODE, 811800, "A", ZINT_ERROR_INVALID_OPTION, 811800, 0, 0, "Error 473: Invalid ECI", "" }, /* 23*/ { BARCODE_HIBC_PDF, UNICODE_MODE, -1, ",", ZINT_ERROR_INVALID_DATA, 0, 0, 0, "Error 203: Invalid characters in data", "" }, /* 24*/ { BARCODE_HIBC_MICPDF, UNICODE_MODE, -1, ",", ZINT_ERROR_INVALID_DATA, 0, 0, 0, "Error 203: Invalid characters in data", "" }, + /* 25*/ { BARCODE_PDF417, UNICODE_MODE, -1, "AB{} C#+ de{} {}F 12{} G{} H", 0, 0, 12, 120, "(36) 28 1 865 807 896 782 855 626 807 94 865 807 896 808 776 839 176 808 32 776 839 806 208", "" }, + /* 26*/ { BARCODE_PDF417, UNICODE_MODE, -1, "{} #+ de{} 12{} {} H", 0, 0, 10, 120, "(30) 22 865 807 896 808 470 807 94 865 807 896 808 32 776 839 806 865 807 896 787 900 900", "" }, }; int data_size = ARRAY_SIZE(data); @@ -366,19 +368,112 @@ static void test_encode(int index, int generate, int debug) { "111111110101010001010111100111100010001100001100010100001100011101101110101100111100011010111100111110111111101000101001" "111111110101010001110101110000110011000000101110010110001001110000101011001000111111011101011100110000111111101000101001" }, - /* 7*/ { BARCODE_PDF417, -1, UNICODE_MODE, 1, 4, "\177\177\177\177\177\177\177\177\177\177\177", 0, 4, 137, 1, "Byte Compaction", + /* 7*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "1234567890123456789012345678901234567890123", 0, 9, 120, 1, "Numeric Compaction 43 consecutive", + "111111110101010001111101010111110011010110001110000100111101111010001101001101110000011111010101111100111111101000101001" + "111111110101010001111010100001000011010011100001000110100111101100001110000101100001011110101001000000111111101000101001" + "111111110101010001010100111100000011111010111000010110010010011111001000011010000111010101000011110000111111101000101001" + "111111110101010001101011110011111011100010001001110110011011000110001001000110011000011010111100111110111111101000101001" + "111111110101010001101011100000100010010111101000000111000010111011001001101111101000011110101110011100111111101000101001" + "111111110101010001111101011110110010001111001000100110110010111100001100011111001001011110101111101100111111101000101001" + "111111110101010001110100111011111010000110001100100110010001110111101001001110111000011101001110111110111111101000101001" + "111111110101010001111110100101110010100111100001000110000101111001101110010110000100010101111110111000111111101000101001" + "111111110101010001111110100110010011100100111110100100111110011000101001111000010001011111010011101000111111101000101001" + }, + /* 8*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "12345678901234567890123456789012345678901234", 0, 9, 120, 1, "Numeric Compaction 44 consecutive", + "111111110101010001111101010111110011010110001110000100111101111010001000100011000011011111010101111100111111101000101001" + "111111110101010001111010100001000011101001100100000111010001100001001110010000001101011110101001000000111111101000101001" + "111111110101010001010100111100000011111100010110100101001100001111101010110011111000010101000011110000111111101000101001" + "111111110101010001101011110011111010010111100111100100110011100001101000111011101000011010111100111110111111101000101001" + "111111110101010001101011100000100011111000010100110110001011100100001011111001011100011110101110011100111111101000101001" + "111111110101010001111101011110110010101101111100000101110001100111001100011111001001011110101111101100111111101000101001" + "111111110101010001110100111011111010000110001100100100001011011000001000100000100100011101001110111110111111101000101001" + "111111110101010001111110100101110011100110011101000100110001011111101101001110000001010101111110111000111111101000101001" + "111111110101010001111110100110010010111001100011100101000110111110001001100001000111011111010011101000111111101000101001" + }, + /* 9*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "123456789012345678901234567890123456789012345", 0, 9, 120, 1, "Numeric Compaction 45 consecutive", + "111111110101010001111101010111110011010110001110000100111101111010001000100011000011011111010101111100111111101000101001" + "111111110101010001111010100001000011101001100100000111010001100001001110010000001101011110101001000000111111101000101001" + "111111110101010001010100111100000011111100010110100101001100001111101010110011111000010101000011110000111111101000101001" + "111111110101010001101011110011111010010111100111100100110011100001101000111011101000011010111100111110111111101000101001" + "111111110101010001101011100000100011111000010100110110001011100100001011111001011100011110101110011100111111101000101001" + "111111110101010001111101011110110010101101111100000101110001100111001010110011111000011110101111101100111111101000101001" + "111111110101010001110100111011111010000110001100100100001001000010001000010001001000011101001110111110111111101000101001" + "111111110101010001111110100101110011110001001101100111101001110011101101111010111110010101111110111000111111101000101001" + "111111110101010001111110100110010011011110011001110110011100100011101100100100011111011111010011101000111111101000101001" + }, + /* 10*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567", 0, 14, 120, 1, "Numeric Compaction 87 consecutive", + "111111110101010001111010100111100011111010111111010100111101111010001000100011000011011111010101111100111111101000101001" + "111111110101010001111110101000111011101001100100000111010001100001001110010000001101011111101010011100111111101000101001" + "111111110101010001010100111100000011111100010110100101001100001111101010110011111000011101010001111110111111101000101001" + "111111110101010001111101011111101010010111100111100100110011100001101000111011101000011010111100111110111111101000101001" + "111111110101010001110101110000110011111000010100110110001011100100001011111001011100011101011100011000111111101000101001" + "111111110101010001111101011110110010101101111100000101110001100111001111101001110100011101011111010000111111101000101001" + "111111110101010001101001110011110011000100011011100111101110000101101101101000010000011101001110111110111111101000101001" + "111111110101010001111101001011000010011000111110100101110000101111101100000100011101010101111110011100111111101000101001" + "111111110101010001111110100110010010000110011011110110011111010001001000011110110110010100110000111110111111101000101001" + "111111110101010001010001110111000011011110111000010100110001100000101111101011111101010100011000011000111111101000101001" + "111111110101010001110100111000110010111101101111100111110000101001101011111101011000011101001110011000111111101000101001" + "111111110101010001101000100011111011000111110010010100000100010111101011111001100100011010001101111110111111101000101001" + "111111110101010001010000010100000011110111001001100110100000100110001110111100011010011010000111011110111111101000101001" + "111111110101010001111101000100011011100101110011000111100011001101001000001011110001011110100010010000111111101000101001" + }, + /* 11*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", 0, 14, 120, 1, "Numeric Compaction 88 consecutive", + "111111110101010001111010100111100011111010111111010100111101111010001000100011000011011111010101111100111111101000101001" + "111111110101010001111110101000111011101001100100000111010001100001001110010000001101011111101010011100111111101000101001" + "111111110101010001010100111100000011111100010110100101001100001111101010110011111000011101010001111110111111101000101001" + "111111110101010001111101011111101010010111100111100100110011100001101000111011101000011010111100111110111111101000101001" + "111111110101010001110101110000110011111000010100110110001011100100001011111001011100011101011100011000111111101000101001" + "111111110101010001111101011110110010101101111100000101110001100111001111011111010111011101011111010000111111101000101001" + "111111110101010001101001110011110011101100001001100110001001100011101110100110001111011101001110111110111111101000101001" + "111111110101010001111101001011000010100111110001100111110110010100001101100111100001010101111110011100111111101000101001" + "111111110101010001111110100110010011001000100111110101111110111001001011111011001000010100110000111110111111101000101001" + "111111110101010001010001110111000011111001010111110100000100011011001110110000010110010100011000011000111111101000101001" + "111111110101010001110100111000110011100010011001000100100011110100001011111101011000011101001110011000111111101000101001" + "111111110101010001101000100011111011000111110010010100011110100000101001110011011100011010001101111110111111101000101001" + "111111110101010001010000010100000011100010110011110111011001100111001110011010000110011010000111011110111111101000101001" + "111111110101010001111101000100011011110010110000110111011100111100101111010000110011011110100010010000111111101000101001" + }, + /* 12*/ { BARCODE_PDF417, -1, UNICODE_MODE, 2, 3, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 0, 14, 120, 1, "Numeric Compaction 89 consecutive", + "111111110101010001111010100111100011111010111111010100111101111010001000100011000011011111010101111100111111101000101001" + "111111110101010001111110101000111011101001100100000111010001100001001110010000001101011111101010011100111111101000101001" + "111111110101010001010100111100000011111100010110100101001100001111101010110011111000011101010001111110111111101000101001" + "111111110101010001111101011111101010010111100111100100110011100001101000111011101000011010111100111110111111101000101001" + "111111110101010001110101110000110011111000010100110110001011100100001011111001011100011101011100011000111111101000101001" + "111111110101010001111101011110110010101101111100000101110001100111001111011111010111011101011111010000111111101000101001" + "111111110101010001101001110011110011101100001001100110001001100011101110100110001111011101001110111110111111101000101001" + "111111110101010001111101001011000010100111110001100111110110010100001101100111100001010101111110011100111111101000101001" + "111111110101010001111110100110010011001000100111110101111110111001001011111011001000010100110000111110111111101000101001" + "111111110101010001010001110111000011111001010111110100000100011011001110110000010110010100011000011000111111101000101001" + "111111110101010001110100111000110011100010011001000100100011110100001110101100010000011101001110011000111111101000101001" + "111111110101010001101000100011111011000111110010010110010001011111001111010011110001011010001101111110111111101000101001" + "111111110101010001010000010100000011100110011001110100111011110110001100010000100110011010000111011110111111101000101001" + "111111110101010001111101000100011011100101110001100110001001110100001010001111000001011110100010010000111111101000101001" + }, + /* 13*/ { BARCODE_PDF417, -1, UNICODE_MODE, 0, 3, "AB{} C#+ de{} {}F 12{} G{} H", 0, 10, 120, 0, "Text Compaction newtable, BWIPP uses PUNCT_SHIFT better for less codewords", + "111111110101010001110101001110000011010111000111100111101010111100001000111011100100011111010101111100111111101000101001" + "111111110101010001111101010110000011100000101100010100111110100111001110001100011101011111010100110000111111101000101001" + "111111110101010001010100111100000010111111001110100100001101011100001001111101101000011010101111100000111111101000101001" + "111111110101010001010111110111110010100011101110000100011101110010001100000101001100011010111100111110111111101000101001" + "111111110101010001101011100100000010011111010011100110000010111010001111101111011101011010111000100000111111101000101001" + "111111110101010001111101011110110010111111011100100101101000011100001100111110110110011111010111000010111111101000101001" + "111111110101010001010011100111000011010111100111110110001100001000101100001101110111011101001110111110111111101000101001" + "111111110101010001101011111000111011100000101100100110100000011101001111101111011101011010111111011110111111101000101001" + "111111110101010001111110100110010010111111011100100110001111001011001011001100111100010100110111110000111111101000101001" + "111111110101010001010001100000110010000110001100100110011100110100001100100100110000010100011000011000111111101000101001" + }, + /* 14*/ { BARCODE_PDF417, -1, UNICODE_MODE, 1, 4, "\177\177\177\177\177\177\177\177\177\177\177", 0, 4, 137, 1, "Byte Compaction", "11111111010101000111101010111100001101011011100000010000010000100010111001001100111101000010100001000011101010011100000111111101000101001" "11111111010101000111110101001100001110010000111011010100111110000110111101001100001101111101000100011011111101010111000111111101000101001" "11111111010101000110101001111100001010000001011110010100000010111100101000000101111001010000001011110011010100111110000111111101000101001" "11111111010101000101011110011110001010001000001000011011000010100000111000110001001101100111000110010010101111101111100111111101000101001" }, - /* 8*/ { BARCODE_PDF417, -1, UNICODE_MODE, 1, 4, "\177\177\177\177\177\177\177\177\177\177\177\177", 0, 4, 137, 1, "Byte Compaction, mod 6 == 0 (924 emitted)", + /* 15*/ { BARCODE_PDF417, -1, UNICODE_MODE, 1, 4, "\177\177\177\177\177\177\177\177\177\177\177\177", 0, 4, 137, 1, "Byte Compaction, mod 6 == 0 (924 emitted)", "11111111010101000111101010111100001101011011100000011000111000110100111001001100111101000010100001000011101010011100000111111101000101001" "11111111010101000111110101001100001110010000111011010100111110000110111101001100001101111001010010000011111101010111000111111101000101001" "11111111010101000110101001111100001001110000100110010011000100001110101000011001111101101000101111100011010100111110000111111101000101001" "11111111010101000101011110011110001101000100011000010011000111001100110001100001000101110100010111000010101111101111100111111101000101001" }, - /* 9*/ { BARCODE_PDF417, -1, UNICODE_MODE, -1, 5, "ABCDEF1234567890123\177\177\177\177VWXYZ", 0, 6, 154, 1, "Text, Numeric, Byte, Text", + /* 16*/ { BARCODE_PDF417, -1, UNICODE_MODE, -1, 5, "ABCDEF1234567890123\177\177\177\177VWXYZ", 0, 6, 154, 1, "Text, Numeric, Byte, Text", "1111111101010100011110101011110000110101110111100001111010101111000010100111001110000110100000101100001001111011110100011110101001111000111111101000101001" "1111111101010100011110101000010000111101011001100001010011110000100011111100011101010110000010111000101111001011011000011111101010111000111111101000101001" "1111111101010100011101010011111100110011111101100101010000001011110010100000010111100101000000101111001010000001011110010101000011110000111111101000101001" @@ -386,7 +481,7 @@ static void test_encode(int index, int generate, int debug) { "1111111101010100011010111000001000101111110101100001011111101011000011001011111001110111100100100100001011111101011000011101011100110000111111101000101001" "1111111101010100011111010111100110110111110110011001101001011111000010101110011111100100100001000111101011000000101110011110101111101100111111101000101001" }, - /* 10*/ { BARCODE_PDF417COMP, -1, UNICODE_MODE, 1, 2, "PDF417 APK", 0, 6, 69, 0, "ISO 15438:2015 Figure G.1, same, BWIPP uses different encodation, same codeword count", + /* 17*/ { BARCODE_PDF417COMP, -1, UNICODE_MODE, 1, 2, "PDF417 APK", 0, 6, 69, 0, "ISO 15438:2015 Figure G.1, same, BWIPP uses different encodation, same codeword count", "111111110101010001111010101111000011010100001100000111011101100110001" "111111110101010001111010100010000011010000111000100111101000101000001" "111111110101010001110101011111100010110011011110000100111110011000101" @@ -394,7 +489,7 @@ static void test_encode(int index, int generate, int debug) { "111111110101010001111010111000111011011000001111010110010011101000001" "111111110101010001111010111101000011110100111101000110010010011111001" }, - /* 11*/ { BARCODE_PDF417COMP, -1, UNICODE_MODE, 4, 4, "ABCDEFG", 0, 10, 103, 1, "", + /* 18*/ { BARCODE_PDF417COMP, -1, UNICODE_MODE, 4, 4, "ABCDEFG", 0, 10, 103, 1, "", "1111111101010100011101010011100000110101000011000001111010101111000010100111001110000110100000101100001" "1111111101010100011110101000000100110100000011100101011111101011000010111111010110000101111110101100001" "1111111101010100011010100111110000101111001100011001000001111010100010011111001100100111001011111001001" @@ -406,7 +501,7 @@ static void test_encode(int index, int generate, int debug) { "1111111101010100010100110011111000100110000110111101100111000010111010010001011110000110011111010001001" "1111111101010100010100011000001100110001101010000001100011000110011011001001101110000111110111110101001" }, - /* 12*/ { BARCODE_HIBC_PDF, -1, UNICODE_MODE, -1, 3, "H123ABC01234567890D", 0, 8, 120, 0, "BWIPP uses different encodation, same codeword count but zint half-pad shorter", + /* 19*/ { BARCODE_HIBC_PDF, -1, UNICODE_MODE, -1, 3, "H123ABC01234567890D", 0, 8, 120, 0, "BWIPP uses different encodation, same codeword count but zint half-pad shorter", "111111110101010001111101010111110011101011001111000100000100010010001110001110100010011111010101111100111111101000101001" "111111110101010001111110101000111011110000010001010110101111110111101111100011101101011110101001000000111111101000101001" "111111110101010001010100111100000011111010111101100100001111000101001100101000011111011101010001111110111111101000101001" @@ -416,7 +511,7 @@ static void test_encode(int index, int generate, int debug) { "111111110101010001110100111011111010100110001100000110100011100111101111010010111100011101001110111110111111101000101001" "111111110101010001111101001011000011100001001100100111010000011001001111011000110100010101111110111000111111101000101001" }, - /* 13*/ { BARCODE_HIBC_PDF, -1, UNICODE_MODE, 1, 3, "A123BJC5D6E71", 0, 6, 120, 1, "BWIPP example", + /* 20*/ { BARCODE_HIBC_PDF, -1, UNICODE_MODE, 1, 3, "A123BJC5D6E71", 0, 6, 120, 1, "BWIPP example", "111111110101010001111010101111000011110101101111100100000100010010001000011011100110011111010101111100111111101000101001" "111111110101010001111010100010000011110000010001010110101111110111101111000001000101011111101010111000111111101000101001" "111111110101010001010100111100000010110001100011110101111110111101101000111100011011010101000111100000111111101000101001" @@ -424,7 +519,7 @@ static void test_encode(int index, int generate, int debug) { "111111110101010001111010111000111011010111110011100110100000011100101111110101000111011101011100110000111111101000101001" "111111110101010001111101011110110010011100110011100100011110110011001011001011100000011110101111000100111111101000101001" }, - /* 14*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 1, "ABCDEFGHIJKLMNOPQRSTUV", 0, 20, 38, 1, "ISO 24728:2006 Figure 1 1st 1x20, same", + /* 21*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 1, "ABCDEFGHIJKLMNOPQRSTUV", 0, 20, 38, 1, "ISO 24728:2006 Figure 1 1st 1x20, same", "11110101001000011000110010011110101001" "11100101001111110101011100011100101001" "11101101001010011001111100011101101001" @@ -446,7 +541,7 @@ static void test_encode(int index, int generate, int debug) { "11011101001111011111011010011011101001" "11011001001100010001110100011011001001" }, - /* 15*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCD", 0, 20, 55, 1, "ISO 24728:2006 Figure 1 2nd 2x20, same", + /* 22*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCD", 0, 20, 55, 1, "ISO 24728:2006 Figure 1 2nd 2x20, same", "1111010100100001100011001001111010101111000011110101001" "1110010100110101111110111101111101000100110011100101001" "1110110100101101100111100001011001110011111011101101001" @@ -468,7 +563,7 @@ static void test_encode(int index, int generate, int debug) { "1101110100111010110011110001000001001101100011011101001" "1101100100111100110110100001001001111001000011011001001" }, - /* 16*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 3, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN", 0, 20, 82, 1, "ISO 24728:2006 Figure 1 3rd 3x20", + /* 23*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 3, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN", 0, 20, 82, 1, "ISO 24728:2006 Figure 1 3rd 3x20", "1100100010100001100011001001011110010111101010111100001010011100111000011100101101" "1110100010111110100010011001011110110101000011111001101001011110010000011000101101" "1110110010111100010111101001001110110110111011001111001001100001000111011000101001" @@ -490,7 +585,7 @@ static void test_encode(int index, int generate, int debug) { "1111010100101111011110100001011001000111110011010111101011110111110110011010000101" "1110010100110010001111011001011001100111000010111011001110001011100110011011000101" }, - /* 17*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 4, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB", 0, 20, 99, 1, "ISO 24728:2006 Figure 1 4th 4x20, same", + /* 24*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 4, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB", 0, 20, 99, 1, "ISO 24728:2006 Figure 1 4th 4x20, same", "110010001010000110001100100111101010111100001011110010101001110011100001101000001011000011100101101" "111010001010100001111100110100101111001000001011110110111011011110011001101100111100100011000101101" "111011001010011000010001110110011101000011101001110110110111100101100001000001010111100011000101001" @@ -512,7 +607,7 @@ static void test_encode(int index, int generate, int debug) { "111101010011100011101010000110001011101111001011001000111110111101011001100101110111100011010000101" "111001010010001000001111010111100010100001001011001100100111101101111101001110100111110011011000101" }, - /* 18*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 1, "123456789012345", 0, 14, 38, 1, "Number Compaction", + /* 25*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 1, "123456789012345", 0, 14, 38, 1, "Number Compaction", "11101110101011111101001100011101110101" "11100110101110101011111100011100110101" "11110110101000001011001100011110110101" @@ -528,7 +623,7 @@ static void test_encode(int index, int generate, int debug) { "11100101001101011110000110011100101001" "11101101001101000111111001011101101001" }, - /* 19*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "\177\177\177", 0, 8, 55, 1, "Byte Compaction", + /* 26*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "\177\177\177", 0, 8, 55, 1, "Byte Compaction", "1100100010100000100001000101010000010010000011001000101" "1110100010111110100010001101111101000100011011101000101" "1110110010110001111100100101100011111001001011101100101" @@ -538,7 +633,7 @@ static void test_encode(int index, int generate, int debug) { "1100111010111001111001100101000001001101100011001110101" "1110111010111000101111011101110001000011010011101110101" }, - /* 20*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "\177\177\177\177\177\177", 0, 8, 55, 1, "Byte Compaction, mod 6 == 0 (924 emitted)", + /* 27*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 2, "\177\177\177\177\177\177", 0, 8, 55, 1, "Byte Compaction, mod 6 == 0 (924 emitted)", "1100100010110001110001101001110010011001111011001000101" "1110100010100010001111010001110010000111011011101000101" "1110110010101000011001111101101000101111100011101100101" @@ -548,7 +643,7 @@ static void test_encode(int index, int generate, int debug) { "1100111010100100010000100001110111101100001011001110101" "1110111010111110011010100001101100001111010011101110101" }, - /* 21*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 3, "ABCDEFG\177\177\177", 0, 8, 82, 1, "Text & Byte Compaction", + /* 28*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 3, "ABCDEFG\177\177\177", 0, 8, 82, 1, "Text & Byte Compaction", "1100111010100001100011001001000010110111101010111100001010011100111000011001110101" "1110111010111110100010011001000010010110100000011100101101111110101110011101110101" "1110011010101000000101111001000011010101000000101111001010000001011110011100110101" @@ -558,7 +653,7 @@ static void test_encode(int index, int generate, int debug) { "1100001010111110111010111001001100010110011100011000101101100001100110011000010101" "1100011010110100011100001001001110010110110000111101001100011011110010011000110101" }, - /* 22*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 4, "\177\177\177abcdefgh1234567890123", 0, 8, 99, 1, "Byte & Text & Numeric Compaction", + /* 29*/ { BARCODE_MICROPDF417, -1, UNICODE_MODE, -1, 4, "\177\177\177abcdefgh1234567890123", 0, 8, 99, 1, "Byte & Text & Numeric Compaction", "110011101010000010000100010101000001001000001000010110101000001001000001010000010010000011001110101" "111011101010111111010110000110000010111001001000010010111101011100111001110100111001100011101110101" "111001101011111001011110110101100110011110001000011010100001111000101001111110101100010011100110101" @@ -568,7 +663,7 @@ static void test_encode(int index, int generate, int debug) { "110000101011000011010000100100000101101100001001100010101110111110111001111001110010110011000010101" "110001101011101110111100010100100011110100001001110010100000101111000101111001010010000011000110101" }, - /* 23*/ { BARCODE_HIBC_MICPDF, -1, UNICODE_MODE, -1, 4, "H123ABC01234567890D", 0, 8, 99, 0, "BWIPP uses different encodation, same codeword count but zint full-pad shorter", + /* 30*/ { BARCODE_HIBC_MICPDF, -1, UNICODE_MODE, -1, 4, "H123ABC01234567890D", 0, 8, 99, 0, "BWIPP uses different encodation, same codeword count but zint full-pad shorter", "110011101010000110001100100100000100010010001000010110111000111010001001000001001100011011001110101" "111011101011010111111011110111110001110110101000010010111101011100111001011111101001100011101110101" "111001101011001010000111110100011110101000001000011010100111110001101001011011000111100011100110101" @@ -578,7 +673,7 @@ static void test_encode(int index, int generate, int debug) { "110000101010110110001000000111000101100111101001100010110111101110000101100010101100000011000010101" "110001101011110110000011010111100100001101101001110010101101011111100001111001000110011011000110101" }, - /* 24*/ { BARCODE_HIBC_MICPDF, -1, UNICODE_MODE, -1, 1, "/EAH783", 0, 17, 38, 1, "HIBC Provider Applications Standard (PAS) example", + /* 31*/ { BARCODE_HIBC_MICPDF, -1, UNICODE_MODE, -1, 1, "/EAH783", 0, 17, 38, 1, "HIBC Provider Applications Standard (PAS) example", "11001101001100011111001001011001101001" "11011101001000001000100100011011101001" "11011001001000100011110100011011001001" @@ -597,7 +692,7 @@ static void test_encode(int index, int generate, int debug) { "11010000101101100100001111011010000101" "11011000101110111000100010011011000101" }, - /* 25*/ { BARCODE_PDF417, 9, DATA_MODE, -1, -1, "\342", 0, 7, 103, 1, "β", + /* 32*/ { BARCODE_PDF417, 9, DATA_MODE, -1, -1, "\342", 0, 7, 103, 1, "β", "1111111101010100011111010101111100110101000110000001100011100011001011110101011110000111111101000101001" "1111111101010100011111010100011000111110101000011001011111100100011011110101001000000111111101000101001" "1111111101010100011101010111111000110110010011110001100011111001001011010100011111000111111101000101001" @@ -606,7 +701,7 @@ static void test_encode(int index, int generate, int debug) { "1111111101010100011110101111010000100011110001000101000110010111000011110101111000010111111101000101001" "1111111101010100011101001110111110101110001110001001010001101100000011010011101111000111111101000101001" }, - /* 26*/ { BARCODE_MICROPDF417, 9, DATA_MODE, -1, 1, "\342\343", 0, 14, 38, 1, "βγ", + /* 33*/ { BARCODE_MICROPDF417, 9, DATA_MODE, -1, 1, "\342\343", 0, 14, 38, 1, "βγ", "11101110101001111110010110011101110101" "11100110101101010000111110011100110101" "11110110101000001000010001011110110101" @@ -976,6 +1071,106 @@ static void test_fuzz(int index, int debug) { testFinish(); } +#include + +// Not a real test, just performance indicator +static void test_perf(int index, int debug) { + + if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ + return; + } + + int ret; + struct item { + int symbology; + int input_mode; + int option_1; + int option_2; + char *data; + int ret; + + int expected_rows; + int expected_width; + char *comment; + }; + struct item data[] = { + /* 0*/ { BARCODE_PDF417, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" + "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" + "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" + "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" + "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", + 0, 40, 307, "960 chars, text/numeric" }, + /* 1*/ { BARCODE_PDF417, DATA_MODE, -1, -1, + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240" + "\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240\240", + 0, 51, 358, "960 chars, byte" }, + }; + int data_size = ARRAY_SIZE(data); + + clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + diff_encode = diff_buffer = 0; + + for (int j = 0; j < 1000; j++) { + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); + + start = clock(); + ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); + diff_encode += clock() - start; + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + 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); + + start = clock(); + ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); + diff_buffer += clock() - start; + assert_zero(ret, "i:%d ZBarcode_Buffer ret %d != 0 (%s)\n", i, ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + + printf("%s: diff_encode %gms, diff_buffer %gms\n", data[i].comment, diff_encode * 1000.0 / CLOCKS_PER_SEC, diff_buffer * 1000.0 / CLOCKS_PER_SEC); + + total_encode += diff_encode; + total_buffer += diff_buffer; + } + if (index != -1) { + printf("totals: encode %gms, buffer %gms\n", total_encode * 1000.0 / CLOCKS_PER_SEC, total_buffer * 1000.0 / CLOCKS_PER_SEC); + } +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ @@ -984,6 +1179,7 @@ int main(int argc, char *argv[]) { { "test_input", test_input, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 }, + { "test_perf", test_perf, 1, 0, 1 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 1eefb5a3..93739cdf 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -32,7 +32,7 @@ #include "testcommon.h" #include -extern int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); static void test_pixel_plot(int index, int debug) { @@ -91,7 +91,7 @@ static void test_pixel_plot(int index, int debug) { symbol->bitmap = (unsigned char *) data_buf; - ret = png_pixel_plot(symbol, data_buf); + ret = png_pixel_plot(symbol, (unsigned char *) data_buf); assert_zero(ret, "i:%d png_pixel_plot ret %d != 0 (%s)\n", i, ret, symbol->errtxt); ret = testUtilVerifyIdentify(symbol->outfile, debug); @@ -118,47 +118,53 @@ static void test_print(int index, int generate, int debug) { int symbology; int input_mode; int output_options; + int whitespace_width; int show_hrt; int option_1; int option_2; int height; float scale; + char *fgcolour; + char *bgcolour; char *data; char *composite; char *expected_file; char *comment; }; struct item data[] = { - /* 0*/ { BARCODE_CODE128, UNICODE_MODE, BOLD_TEXT, -1, -1, -1, 0, 0, "Égjpqy", "", "../data/png/code128_egrave_bold.png", "" }, - /* 1*/ { BARCODE_CODE128, UNICODE_MODE, BOLD_TEXT | BARCODE_BOX, -1, -1, -1, 0, 0, "Égjpqy", "", "../data/png/code128_egrave_bold_box3.png", "" }, - /* 2*/ { BARCODE_GS1_128_CC, -1, -1, -1, 3, -1, 0, 0, "[00]030123456789012340", "[02]13012345678909[37]24[10]1234567ABCDEFG", "../data/png/gs1_128_cc_fig12.png", "" }, - /* 3*/ { BARCODE_CODABLOCKF, -1, -1, -1, 3, -1, 0, 0, "AAAAAAAAA", "", "../data/png/codablockf_3rows.png", "" }, - /* 4*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "9771384524017+12", "", "../data/png/ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, - /* 5*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "9780877799306+54321", "", "../data/png/ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, - /* 6*/ { BARCODE_EANX_CC, -1, -1, -1, 1, -1, 0, 0, "123456789012+12", "[91]123456789012345678901", "../data/png/ean13_cc_2addon_cca_4x4.png", "" }, - /* 7*/ { BARCODE_EANX_CC, -1, -1, -1, 2, -1, 0, 0, "123456789012+54321", "[91]1234567890", "../data/png/ean13_cc_5addon_ccb_3x4.png", "" }, - /* 8*/ { BARCODE_EANX_CC, -1, -1, 0, 2, -1, 0, 0, "123456789012+54321", "[91]1234567890", "../data/png/ean13_cc_5addon_ccb_3x4_notext.png", "" }, - /* 9*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, 0, 0, "012345678905+24", "", "../data/png/upca_2addon_ggs_5.2.6.6-5.png", "" }, - /* 10*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, 0, 0, "614141234417+12345", "", "../data/png/upca_5addon.png", "" }, - /* 11*/ { BARCODE_UPCA, -1, -1, 0, -1, -1, 0, 0, "614141234417+12345", "", "../data/png/upca_5addon_notext.png", "" }, - /* 12*/ { BARCODE_UPCA, -1, BARCODE_BIND, -1, -1, -1, 0, 0, "614141234417+12345", "", "../data/png/upca_5addon_bind3.png", "" }, - /* 13*/ { BARCODE_UPCA_CC, -1, -1, -1, 1, -1, 0, 0, "12345678901+12", "[91]123456789", "../data/png/upca_cc_2addon_cca_3x4.png", "" }, - /* 14*/ { BARCODE_UPCA_CC, -1, -1, -1, 2, -1, 0, 0, "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4.png", "" }, - /* 15*/ { BARCODE_UPCA_CC, -1, -1, 0, 2, -1, 0, 0, "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4_notext.png", "" }, - /* 16*/ { BARCODE_UPCA_CC, -1, BARCODE_BIND, -1, 2, -1, 0, 0, "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4_bind3.png", "" }, - /* 17*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, 0, 0, "1234567+12", "", "../data/png/upce_2addon.png", "" }, - /* 18*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, 0, 0, "1234567+12345", "", "../data/png/upce_5addon.png", "" }, - /* 19*/ { BARCODE_UPCE_CC, -1, -1, -1, 1, -1, 0, 0, "0654321+89", "[91]1", "../data/png/upce_cc_2addon_cca_5x2.png", "" }, - /* 20*/ { BARCODE_UPCE_CC, -1, -1, -1, 2, -1, 0, 0, "1876543+56789", "[91]12345", "../data/png/upce_cc_5addon_ccb_8x2.png", "" }, - /* 21*/ { BARCODE_UPCE_CC, -1, -1, 0, 2, -1, 0, 0, "1876543+56789", "[91]12345", "../data/png/upce_cc_5addon_ccb_8x2_notext.png", "" }, - /* 22*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "1234567+12", "", "../data/png/ean8_2addon.png", "" }, - /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "1234567+12345", "", "../data/png/ean8_5addon.png", "" }, - /* 24*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0, 0, "9876543+65", "[91]1234567", "../data/png/ean8_cc_2addon_cca_4x3.png", "" }, - /* 25*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0, 0, "9876543+74083", "[91]123456789012345678", "../data/png/ean8_cc_5addon_ccb_8x3.png", "" }, - /* 26*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "12345", "", "../data/png/ean5.png", "" }, - /* 27*/ { BARCODE_EANX, -1, -1, -1, -1, -1, 0, 0, "12", "", "../data/png/ean2.png", "" }, - /* 28*/ { BARCODE_CODE39, -1, SMALL_TEXT, -1, -1, -1, 0, 0, "123", "", "../data/png/code39_small.png", "" }, - /* 29*/ { BARCODE_POSTNET, -1, -1, -1, -1, -1, 0, 3.5, "12345", "", "../data/png/postnet_zip.png", "300 dpi, using 1/43in X, 300 / 43 / 2 = ~3.5 scale" }, + /* 0*/ { BARCODE_CODE128, UNICODE_MODE, BOLD_TEXT, -1, -1, -1, -1, 0, 0, "", "", "Égjpqy", "", "../data/png/code128_egrave_bold.png", "" }, + /* 1*/ { BARCODE_CODE128, UNICODE_MODE, BOLD_TEXT | BARCODE_BOX, -1, -1, -1, -1, 0, 0, "", "", "Égjpqy", "", "../data/png/code128_egrave_bold_box3.png", "" }, + /* 2*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, 3, -1, 0, 0, "", "", "[00]030123456789012340", "[02]13012345678909[37]24[10]1234567ABCDEFG", "../data/png/gs1_128_cc_fig12.png", "" }, + /* 3*/ { BARCODE_CODABLOCKF, -1, -1, -1, -1, 3, -1, 0, 0, "", "", "AAAAAAAAA", "", "../data/png/codablockf_3rows.png", "" }, + /* 4*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9771384524017+12", "", "../data/png/ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, + /* 5*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9780877799306+54321", "", "../data/png/ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, + /* 6*/ { BARCODE_EANX_CC, -1, -1, -1, -1, 1, -1, 0, 0, "", "", "123456789012+12", "[91]123456789012345678901", "../data/png/ean13_cc_2addon_cca_4x4.png", "" }, + /* 7*/ { BARCODE_EANX_CC, -1, -1, -1, -1, 2, -1, 0, 0, "", "", "123456789012+54321", "[91]1234567890", "../data/png/ean13_cc_5addon_ccb_3x4.png", "" }, + /* 8*/ { BARCODE_EANX_CC, -1, -1, -1, 0, 2, -1, 0, 0, "", "", "123456789012+54321", "[91]1234567890", "../data/png/ean13_cc_5addon_ccb_3x4_notext.png", "" }, + /* 9*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "012345678905+24", "", "../data/png/upca_2addon_ggs_5.2.6.6-5.png", "" }, + /* 10*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "614141234417+12345", "", "../data/png/upca_5addon.png", "" }, + /* 11*/ { BARCODE_UPCA, -1, -1, -1, 0, -1, -1, 0, 0, "", "", "614141234417+12345", "", "../data/png/upca_5addon_notext.png", "" }, + /* 12*/ { BARCODE_UPCA, -1, BARCODE_BIND, -1, -1, -1, -1, 0, 0, "", "", "614141234417+12345", "", "../data/png/upca_5addon_bind3.png", "" }, + /* 13*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, 1, -1, 0, 0, "", "", "12345678901+12", "[91]123456789", "../data/png/upca_cc_2addon_cca_3x4.png", "" }, + /* 14*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, 2, -1, 0, 0, "", "", "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4.png", "" }, + /* 15*/ { BARCODE_UPCA_CC, -1, -1, -1, 0, 2, -1, 0, 0, "", "", "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4_notext.png", "" }, + /* 16*/ { BARCODE_UPCA_CC, -1, BARCODE_BIND, -1, -1, 2, -1, 0, 0, "", "", "12345678901+12121", "[91]1234567890123", "../data/png/upca_cc_5addon_ccb_4x4_bind3.png", "" }, + /* 17*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "1234567+12", "", "../data/png/upce_2addon.png", "" }, + /* 18*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "1234567+12345", "", "../data/png/upce_5addon.png", "" }, + /* 19*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, 1, -1, 0, 0, "", "", "0654321+89", "[91]1", "../data/png/upce_cc_2addon_cca_5x2.png", "" }, + /* 20*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, 2, -1, 0, 0, "", "", "1876543+56789", "[91]12345", "../data/png/upce_cc_5addon_ccb_8x2.png", "" }, + /* 21*/ { BARCODE_UPCE_CC, -1, -1, -1, 0, 2, -1, 0, 0, "", "", "1876543+56789", "[91]12345", "../data/png/upce_cc_5addon_ccb_8x2_notext.png", "" }, + /* 22*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "1234567+12", "", "../data/png/ean8_2addon.png", "" }, + /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "1234567+12345", "", "../data/png/ean8_5addon.png", "" }, + /* 24*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9876543+65", "[91]1234567", "../data/png/ean8_cc_2addon_cca_4x3.png", "" }, + /* 25*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9876543+74083", "[91]123456789012345678", "../data/png/ean8_cc_5addon_ccb_8x3.png", "" }, + /* 26*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "12345", "", "../data/png/ean5.png", "" }, + /* 27*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "12", "", "../data/png/ean2.png", "" }, + /* 28*/ { BARCODE_CODE39, -1, SMALL_TEXT, -1, -1, -1, -1, 0, 0, "", "", "123", "", "../data/png/code39_small.png", "" }, + /* 29*/ { BARCODE_POSTNET, -1, -1, -1, -1, -1, -1, 0, 3.5, "", "", "12345", "", "../data/png/postnet_zip.png", "300 dpi, using 1/43in X, 300 / 43 / 2 = ~3.5 scale" }, + /* 30*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, 0, 0, "", "CFCECDCC", "12345", "", "../data/png/pdf417_bgalpha.png", "" }, + /* 31*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, 0, 0, "30313233", "", "12345", "", "../data/png/pdf417_fgalpha.png", "" }, + /* 32*/ { BARCODE_ULTRA, -1, -1, 2, -1, -1, -1, 0, 0, "0000007F", "FF000033", "12345", "", "../data/png/ultra_alpha.png", "" }, }; int data_size = ARRAY_SIZE(data); @@ -195,6 +201,15 @@ static void test_print(int index, int generate, int debug) { if (data[i].output_options & (BARCODE_BOX | BARCODE_BIND)) { symbol->border_width = 3; } + if (data[i].whitespace_width != -1) { + symbol->whitespace_width = data[i].whitespace_width; + } + if (*data[i].fgcolour) { + strcpy(symbol->fgcolour, data[i].fgcolour); + } + if (*data[i].bgcolour) { + strcpy(symbol->bgcolour, data[i].bgcolour); + } if (strlen(data[i].composite)) { text = data[i].composite; strcpy(symbol->primary, data[i].data); @@ -211,10 +226,10 @@ static void test_print(int index, int generate, int debug) { assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); if (generate) { - printf(" /*%3d*/ { %s, %s, %s, %d, %d, %d, %d, %.5g, \"%s\", \"%s\", \"%s\", \"%s\" },\n", + printf(" /*%3d*/ { %s, %s, %s, %d, %d, %d, %d, %d, %.5g, \"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), - data[i].show_hrt, data[i].option_1, data[i].option_2, data[i].height, data[i].scale, testUtilEscape(data[i].data, length, escaped, escaped_size), - data[i].composite, data[i].expected_file, data[i].comment); + data[i].whitespace_width, data[i].show_hrt, data[i].option_1, data[i].option_2, data[i].height, data[i].scale, data[i].fgcolour, data[i].bgcolour, + testUtilEscape(data[i].data, length, escaped, escaped_size), data[i].composite, data[i].expected_file, data[i].comment); ret = rename(symbol->outfile, data[i].expected_file); assert_zero(ret, "i:%d rename(%s, %s) ret %d != 0\n", i, symbol->outfile, data[i].expected_file, ret); if (have_identify) { diff --git a/backend/tests/test_raster.c b/backend/tests/test_raster.c index 57c232de..ebebb53f 100644 --- a/backend/tests/test_raster.c +++ b/backend/tests/test_raster.c @@ -281,7 +281,7 @@ static void test_buffer(int index, int generate, int debug) { assert_zero(ret, "i:%d ZBarcode_Buffer(%s) ret %d != 0 (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); assert_nonnull(symbol->bitmap, "i:%d ZBarcode_Buffer(%s) bitmap NULL\n", i, testUtilBarcodeName(data[i].symbology)); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); if (generate) { printf(" /*%3d*/ { %s, \"%s\", \"%s\", %d, %d, %d, %d, %d },\n", @@ -383,7 +383,7 @@ static void test_upcean_hrt(int index, int debug) { assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); assert_nonnull(symbol->bitmap, "i:%d (%d) symbol->bitmap NULL\n", i, data[i].symbology); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); assert_equal(symbol->height, data[i].expected_height, "i:%d (%s) symbol->height %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->height, data[i].expected_height); assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%s) symbol->rows %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows); @@ -500,7 +500,7 @@ static void test_row_separator(int index, int debug) { int j, separator_bits_set; - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); for (j = data[i].expected_separator_row; j < data[i].expected_separator_row + data[i].expected_separator_height; j++) { separator_bits_set = is_row_column_black(symbol, j, data[i].expected_separator_col); @@ -580,7 +580,7 @@ static void test_stacking(int index, int debug) { int j, separator_bits_set; - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); if (data[i].expected_separator_row != -1) { for (j = data[i].expected_separator_row; j < data[i].expected_separator_row + data[i].expected_separator_height; j++) { @@ -722,7 +722,7 @@ static void test_output_options(int index, int debug) { if (ret < 5) { assert_nonnull(symbol->bitmap, "i:%d (%s) symbol->bitmap NULL\n", i, testUtilBarcodeName(data[i].symbology)); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); assert_equal(symbol->height, data[i].expected_height, "i:%d (%s) symbol->height %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->height, data[i].expected_height); assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%s) symbol->rows %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows); @@ -802,7 +802,7 @@ static void test_draw_string_wrap(int index, int debug) { assert_equal(symbol->bitmap_width, data[i].expected_bitmap_width, "i:%d (%d) symbol->bitmap_width %d != %d\n", i, data[i].symbology, symbol->bitmap_width, data[i].expected_bitmap_width); assert_equal(symbol->bitmap_height, data[i].expected_bitmap_height, "i:%d (%d) symbol->bitmap_height %d != %d\n", i, data[i].symbology, symbol->bitmap_height, data[i].expected_bitmap_height); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); ret = ZBarcode_Print(symbol, 0); assert_zero(ret, "i:%d ZBarcode_Print(%d) ret %d != 0\n", i, data[i].symbology, ret); @@ -868,7 +868,7 @@ static void test_code128_utf8(int index, int debug) { assert_equal(symbol->bitmap_width, data[i].expected_bitmap_width, "i:%d (%d) symbol->bitmap_width %d != %d\n", i, BARCODE_CODE128, symbol->bitmap_width, data[i].expected_bitmap_width); assert_equal(symbol->bitmap_height, data[i].expected_bitmap_height, "i:%d (%d) symbol->bitmap_height %d != %d\n", i, BARCODE_CODE128, symbol->bitmap_height, data[i].expected_bitmap_height); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); ret = ZBarcode_Print(symbol, 0); assert_zero(ret, "i:%d ZBarcode_Print(%d) ret %d != 0\n", i, BARCODE_CODE128, ret); @@ -972,7 +972,7 @@ static void test_scale(int index, int debug) { assert_zero(ret, "i:%d ZBarcode_Buffer(%d) ret %d != 0\n", i, data[i].symbology, ret); assert_nonnull(symbol->bitmap, "i:%d (%d) symbol->bitmap NULL\n", i, data[i].symbology); - if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol); + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); assert_equal(symbol->height, data[i].expected_height, "i:%d (%d) symbol->height %d != %d\n", i, data[i].symbology, symbol->height, data[i].expected_height); assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%d) symbol->rows %d != %d\n", i, data[i].symbology, symbol->rows, data[i].expected_rows); @@ -1002,6 +1002,189 @@ static void test_scale(int index, int debug) { testFinish(); } +static void test_buffer_plot(int index, int generate, int debug) { + + testStart(""); + + int ret; + struct item { + int symbology; + int option_1; + int option_2; + int whitespace_width; + int output_options; + char *fgcolour; + char *bgcolour; + char *data; + + int expected_height; + int expected_rows; + int expected_width; + int expected_bitmap_width; + int expected_bitmap_height; + char *expected_bitmap; + }; + struct item data[] = { + /* 0*/ { BARCODE_PDF417, 0, 1, -1, -1, "", "", "1", 15, 5, 86, 86, 15, + "11111111010101000111101010111100001110101001110000011101010111000000111111101000101001" + "11111111010101000111101010111100001110101001110000011101010111000000111111101000101001" + "11111111010101000111101010111100001110101001110000011101010111000000111111101000101001" + "11111111010101000111111010101110001011111101001100011111101010111000111111101000101001" + "11111111010101000111111010101110001011111101001100011111101010111000111111101000101001" + "11111111010101000111111010101110001011111101001100011111101010111000111111101000101001" + "11111111010101000110101011111000001111110101101000011101010111111000111111101000101001" + "11111111010101000110101011111000001111110101101000011101010111111000111111101000101001" + "11111111010101000110101011111000001111110101101000011101010111111000111111101000101001" + "11111111010101000101011110011110001110111101100100011010111101111100111111101000101001" + "11111111010101000101011110011110001110111101100100011010111101111100111111101000101001" + "11111111010101000101011110011110001110111101100100011010111101111100111111101000101001" + "11111111010101000111010111001100001110100111000110011101011100110000111111101000101001" + "11111111010101000111010111001100001110100111000110011101011100110000111111101000101001" + "11111111010101000111010111001100001110100111000110011101011100110000111111101000101001" + }, + /* 1*/ { BARCODE_PDF417, 0, 1, -1, -1, "FF0000", "00FF0099", "1", 15, 5, 86, 86, 15, + "RRRRRRRRGRGRGRGGGRRRRGRGRGRRRRGGGGRRRGRGRGGRRRGGGGGRRRGRGRGRRRGGGGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRRGRGRGRRRRGGGGRRRGRGRGGRRRGGGGGRRRGRGRGRRRGGGGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRRGRGRGRRRRGGGGRRRGRGRGGRRRGGGGGRRRGRGRGRRRGGGGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRRRRGRGRGRRRGGGRGRRRRRRGRGGRRGGGRRRRRRGRGRGRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRRRRGRGRGRRRGGGRGRRRRRRGRGGRRGGGRRRRRRGRGRGRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRRRRGRGRGRRRGGGRGRRRRRRGRGGRRGGGRRRRRRGRGRGRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRGRGRGRRRRRGGGGGRRRRRRGRGRRGRGGGGRRRGRGRGRRRRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRGRGRGRRRRRGGGGGRRRRRRGRGRRGRGGGGRRRGRGRGRRRRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRGRGRGRRRRRGGGGGRRRRRRGRGRRGRGGGGRRRGRGRGRRRRRRGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRGRGRRRRGGRRRRGGGRRRGRRRRGRRGGRGGGRRGRGRRRRGRRRRRGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRGRGRRRRGGRRRRGGGRRRGRRRRGRRGGRGGGRRGRGRRRRGRRRRRGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRGRGRRRRGGRRRRGGGRRRGRRRRGRRGGRGGGRRGRGRRRRGRRRRRGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRGRGRRRGGRRGGGGRRRGRGGRRRGGGRRGGRRRGRGRRRGGRRGGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRGRGRRRGGRRGGGGRRRGRGGRRRGGGRRGGRRRGRGRRRGGRRGGGGRRRRRRRGRGGGRGRGGR" + "RRRRRRRRGRGRGRGGGRRRGRGRRRGGRRGGGGRRRGRGGRRRGGGRRGGRRRGRGRRRGGRRGGGGRRRRRRRGRGGGRGRGGR" + }, + /* 2*/ { BARCODE_PDF417, 0, 1, 1, -1, "FFFF0033", "00FF00", "1", 15, 5, 86, 88, 15, + "GYYYYYYYYGYGYGYGGGYYYYGYGYGYYYYGGGGYYYGYGYGGYYYGGGGGYYYGYGYGYYYGGGGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYYGYGYGYYYYGGGGYYYGYGYGGYYYGGGGGYYYGYGYGYYYGGGGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYYGYGYGYYYYGGGGYYYGYGYGGYYYGGGGGYYYGYGYGYYYGGGGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYYYYGYGYGYYYGGGYGYYYYYYGYGGYYGGGYYYYYYGYGYGYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYYYYGYGYGYYYGGGYGYYYYYYGYGGYYGGGYYYYYYGYGYGYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYYYYGYGYGYYYGGGYGYYYYYYGYGGYYGGGYYYYYYGYGYGYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYGYGYGYYYYYGGGGGYYYYYYGYGYYGYGGGGYYYGYGYGYYYYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYGYGYGYYYYYGGGGGYYYYYYGYGYYGYGGGGYYYGYGYGYYYYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYGYGYGYYYYYGGGGGYYYYYYGYGYYGYGGGGYYYGYGYGYYYYYYGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYGYGYYYYGGYYYYGGGYYYGYYYYGYYGGYGGGYYGYGYYYYGYYYYYGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYGYGYYYYGGYYYYGGGYYYGYYYYGYYGGYGGGYYGYGYYYYGYYYYYGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYGYGYYYYGGYYYYGGGYYYGYYYYGYYGGYGGGYYGYGYYYYGYYYYYGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYGYGYYYGGYYGGGGYYYGYGGYYYGGGYYGGYYYGYGYYYGGYYGGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYGYGYYYGGYYGGGGYYYGYGGYYYGGGYYGGYYYGYGYYYGGYYGGGGYYYYYYYGYGGGYGYGGYG" + "GYYYYYYYYGYGYGYGGGYYYGYGYYYGGYYGGGGYYYGYGGYYYGGGYYGGYYYGYGYYYGGYYGGGGYYYYYYYGYGGGYGYGGYG" + }, + /* 3*/ { BARCODE_ULTRA, -1, -1, -1, -1, "FF00007F", "00FF0000", "1", 13, 13, 13, 13, 13, + "1111111111111" + "10Y10GYCGYYC1" + "11C10MGYCGGG1" + "10G10GYCMCYC1" + "11Y10YMMGYGY1" + "10M10CGGCMYM1" + "1101010101011" + "10G10CYMGCCC1" + "11C10MCGCMMM1" + "10Y10CGCGYCY1" + "11M10GMMMMGC1" + "10C10MYYYGMY1" + "1111111111111" + }, + /* 4*/ { BARCODE_ULTRA, -1, -1, 1, -1, "", "00FF0000", "1", 13, 13, 13, 15, 13, + "G1111111111111G" + "G10Y10GYCGYYC1G" + "G11C10MGYCGGG1G" + "G10G10GYCMCYC1G" + "G11Y10YMMGYGY1G" + "G10M10CGGCMYM1G" + "G1101010101011G" + "G10G10CYMGCCC1G" + "G11C10MCGCMMM1G" + "G10Y10CGCGYCY1G" + "G11M10GMMMMGC1G" + "G10C10MYYYGMY1G" + "G1111111111111G" + }, + /* 5*/ { BARCODE_CHANNEL, -1, -1, 1, -1, "30313233", "CFCECDCC", "1", 5, 1, 19, 21, 5, + "CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132303132CFCECD303132303132CFCECDCFCECDCFCECD303132CFCECD" + "CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132303132CFCECD303132303132CFCECDCFCECDCFCECD303132CFCECD" + "CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132303132CFCECD303132303132CFCECDCFCECDCFCECD303132CFCECD" + "CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132303132CFCECD303132303132CFCECDCFCECDCFCECD303132CFCECD" + "CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132CFCECD303132303132CFCECD303132303132CFCECDCFCECDCFCECD303132CFCECD" + }, + }; + int data_size = ARRAY_SIZE(data); + + int row, column; + int fg_len, bg_len; + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d\n", i); + + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, data[i].symbology, UNICODE_MODE, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, data[i].output_options, data[i].data, -1, debug); + if (data[i].whitespace_width != -1) { + symbol->whitespace_width = data[i].whitespace_width; + } + if (*data[i].fgcolour) { + strcpy(symbol->fgcolour, data[i].fgcolour); + } + if (*data[i].bgcolour) { + strcpy(symbol->bgcolour, data[i].bgcolour); + } + /* Keep dumps small */ + symbol->show_hrt = 0; + symbol->scale = 0.5f; + symbol->height = 1; + + ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); + assert_zero(ret, "i:%d ZBarcode_Encode(%s) ret %d != 0 (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + ret = ZBarcode_Buffer(symbol, 0); + assert_zero(ret, "i:%d ZBarcode_Buffer(%s) ret %d != 0 (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + assert_nonnull(symbol->bitmap, "i:%d ZBarcode_Buffer(%s) bitmap NULL\n", i, testUtilBarcodeName(data[i].symbology)); + + if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) testUtilBitmapPrint(symbol, NULL, NULL); + + if (generate) { + printf(" /*%3d*/ { %s, %d, %d, %d, %s, \"%s\", \"%s\", \"%s\", %d, %d, %d, %d, %d,\n", + i, testUtilBarcodeName(data[i].symbology), data[i].option_1, data[i].option_2, data[i].whitespace_width, testUtilOutputOptionsName(data[i].output_options), + data[i].fgcolour, data[i].bgcolour, data[i].data, symbol->height, symbol->rows, symbol->width, symbol->bitmap_width, symbol->bitmap_height); + testUtilBitmapPrint(symbol, " ", "\n"); + printf(" },\n"); + } else { + assert_equal(symbol->height, data[i].expected_height, "i:%d (%s) symbol->height %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->height, data[i].expected_height); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%s) symbol->rows %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d (%s) symbol->width %d != %d\n", i, testUtilBarcodeName(data[i].symbology), symbol->width, data[i].expected_width); + assert_equal(symbol->bitmap_width, data[i].expected_bitmap_width, "i:%d (%s) symbol->bitmap_width %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->bitmap_width, data[i].expected_bitmap_width); + assert_equal(symbol->bitmap_height, data[i].expected_bitmap_height, "i:%d (%s) symbol->bitmap_height %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->bitmap_height, data[i].expected_bitmap_height); + + ret = testUtilBitmapCmp(symbol, data[i].expected_bitmap, &row, &column); + assert_zero(ret, "i:%d (%s) testUtilBitmapCmp ret %d != 0 column %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, column, row, data[i].data); + + fg_len = strlen(data[i].fgcolour); + bg_len = strlen(data[i].bgcolour); + if (fg_len > 6 || bg_len > 6) { + assert_nonnull(symbol->alphamap, "i:%d ZBarcode_Buffer(%s) alphamap NULL\n", i, testUtilBarcodeName(data[i].symbology)); + // TODO: check alphamap + } else { + assert_null(symbol->alphamap, "i:%d ZBarcode_Buffer(%s) alphamap not NULL\n", i, testUtilBarcodeName(data[i].symbology)); + } + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ @@ -1014,6 +1197,7 @@ int main(int argc, char *argv[]) { { "test_draw_string_wrap", test_draw_string_wrap, 1, 0, 1 }, { "test_code128_utf8", test_code128_utf8, 1, 0, 1 }, { "test_scale", test_scale, 1, 0, 1 }, + { "test_buffer_plot", test_buffer_plot, 1, 1, 1 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_tif.c b/backend/tests/test_tif.c index 344370a4..6ae51a2c 100644 --- a/backend/tests/test_tif.c +++ b/backend/tests/test_tif.c @@ -31,7 +31,7 @@ #include "testcommon.h" -extern int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf); // For overview when debugging: ./test_tiff -f pixel_plot -d 5 static void test_pixel_plot(int index, int debug) { @@ -112,7 +112,7 @@ static void test_pixel_plot(int index, int debug) { symbol->bitmap = (unsigned char *) data_buf; - ret = tif_pixel_plot(symbol, data_buf); + ret = tif_pixel_plot(symbol, (unsigned char *) data_buf); assert_zero(ret, "i:%d tif_pixel_plot ret %d != 0 (%s)\n", i, ret, symbol->errtxt); ret = testUtilVerifyIdentify(symbol->outfile, debug); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 1db41a86..6364231a 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -42,7 +42,10 @@ #include #include +#ifndef COMMON_INLINE extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); +extern int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); +#endif static int tests = 0; static int failed = 0; @@ -656,10 +659,20 @@ int testUtilSymbolCmp(const struct zint_symbol *a, const struct zint_symbol *b) if (a->width != b->width) { return 3; } - for (int i = 0; i < a->rows; i++) { - for (int j = 0; j < a->width; j++) { - if (module_is_set(a, i, j) != module_is_set(b, i, j)) { - return 4; + if (a->symbology == BARCODE_ULTRA) { + for (int i = 0; i < a->rows; i++) { + for (int j = 0; j < a->width; j++) { + if (module_colour_is_set(a, i, j) != module_colour_is_set(b, i, j)) { + return 4; + } + } + } + } else { + for (int i = 0; i < a->rows; i++) { + for (int j = 0; j < a->width; j++) { + if (module_is_set(a, i, j) != module_is_set(b, i, j)) { + return 4; + } } } } @@ -884,21 +897,27 @@ int testUtilVectorCmp(const struct zint_vector *a, const struct zint_vector *b) return 0; } -void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix) { +void testUtilModulesDump(const struct zint_symbol *symbol, const char *prefix, const char *postfix) { int r; for (r = 0; r < symbol->rows; r++) { testUtilModulesDumpRow(symbol, r, prefix, postfix); } } -void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, char *prefix, char *postfix) { +void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, const char *prefix, const char *postfix) { int w; if (*prefix) { fputs(prefix, stdout); } putchar('"'); - for (w = 0; w < symbol->width; w++) { - putchar(module_is_set(symbol, row, w) + '0'); + if (symbol->symbology == BARCODE_ULTRA) { + for (w = 0; w < symbol->width; w++) { + putchar(module_colour_is_set(symbol, row, w) + '0'); + } + } else { + for (w = 0; w < symbol->width; w++) { + putchar(module_is_set(symbol, row, w) + '0'); + } } putchar('"'); if (*postfix) { @@ -910,14 +929,27 @@ int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, i const char *e = expected; const char *ep = expected + strlen(expected); int r, w = 0; - for (r = 0; r < symbol->rows && e < ep; r++) { - for (w = 0; w < symbol->width && e < ep; w++) { - if (module_is_set(symbol, r, w) + '0' != *e) { - *row = r; - *width = w; - return 1 /*fail*/; + if (symbol->symbology == BARCODE_ULTRA) { + for (r = 0; r < symbol->rows && e < ep; r++) { + for (w = 0; w < symbol->width && e < ep; w++) { + if (module_colour_is_set(symbol, r, w) + '0' != *e) { + *row = r; + *width = w; + return 1 /*fail*/; + } + e++; + } + } + } else { + for (r = 0; r < symbol->rows && e < ep; r++) { + for (w = 0; w < symbol->width && e < ep; w++) { + if (module_is_set(symbol, r, w) + '0' != *e) { + *row = r; + *width = w; + return 1 /*fail*/; + } + e++; } - e++; } } *row = r; @@ -929,12 +961,22 @@ int testUtilModulesCmpRow(const struct zint_symbol *symbol, int row, const char const char *e = expected; const char *ep = expected + strlen(expected); int w; - for (w = 0; w < symbol->width && e < ep; w++) { - if (module_is_set(symbol, row, w) + '0' != *e) { - *width = w; - return 1 /*fail*/; + if (symbol->symbology == BARCODE_ULTRA) { + for (w = 0; w < symbol->width && e < ep; w++) { + if (module_colour_is_set(symbol, row, w) + '0' != *e) { + *width = w; + return 1 /*fail*/; + } + e++; + } + } else { + for (w = 0; w < symbol->width && e < ep; w++) { + if (module_is_set(symbol, row, w) + '0' != *e) { + *width = w; + return 1 /*fail*/; + } + e++; } - e++; } *width = w; return e != ep || w != symbol->width ? 1 /*fail*/ : 0 /*success*/; @@ -956,8 +998,14 @@ int testUtilModulesDumpHex(const struct zint_symbol *symbol, char dump[], int du space = 0; } byt = byt << 1; - if (module_is_set(symbol, r, i)) { - byt += 1; + if (symbol->symbology == BARCODE_ULTRA) { + if (module_colour_is_set(symbol, r, i)) { + byt += 1; + } + } else { + if (module_is_set(symbol, r, i)) { + byt += 1; + } } if (d < de && ((i + 1) % 4) == 0) { *d++ = hex[byt]; @@ -1004,35 +1052,103 @@ char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dum return dump; } -void testUtilBitmapPrint(const struct zint_symbol *symbol) { - static char colour[] = { '0', 'C', 'B', 'M', 'R', 'Y', 'G', '1' }; +void testUtilBitmapPrint(const struct zint_symbol *symbol, const char *prefix, const char *postfix) { + static char colour[] = { '0', 'C', 'M', 'B', 'Y', 'G', 'R', '1' }; int row, column, i, j; - fputs(" ", stdout); - for (column = 0; column < symbol->bitmap_width; column += 10) printf("%-3d ", column); - fputs("\n ", stdout); - for (column = 0; column < symbol->bitmap_width; column++) printf("%d", column % 10); - putchar('\n'); + if (!prefix) { + fputs(" ", stdout); + for (column = 0; column < symbol->bitmap_width; column += 10) printf("%-3d ", column); + fputs("\n ", stdout); + for (column = 0; column < symbol->bitmap_width; column++) printf("%d", column % 10); + putchar('\n'); + } for (row = 0; row < symbol->bitmap_height; row++) { - printf("%3d: ", row); + if (!prefix) { + printf("%3d: ", row); + } else { + if (*prefix) { + fputs(prefix, stdout); + } + putchar('"'); + } for (column = 0; column < symbol->bitmap_width; column++) { if (symbol->output_options & OUT_BUFFER_INTERMEDIATE) { putchar(symbol->bitmap[(row * symbol->bitmap_width) + column]); } else { i = ((row * symbol->bitmap_width) + column) * 3; - j = (symbol->bitmap[i] == 0) + (symbol->bitmap[i + 1] == 0) * 2 + (symbol->bitmap[i + 2] == 0) * 4; - putchar(colour[j]); + if ((symbol->bitmap[i] == 0 || symbol->bitmap[i] == 0xff) && (symbol->bitmap[i + 1] == 0 || symbol->bitmap[i + 1] == 0xff) + && (symbol->bitmap[i + 2] == 0 || symbol->bitmap[i + 2] == 0xff)) { + j = (symbol->bitmap[i] == 0) + (symbol->bitmap[i + 1] == 0) * 2 + (symbol->bitmap[i + 2] == 0) * 4; + putchar(colour[j]); + } else { + printf("%02X%02X%02X", symbol->bitmap[i], symbol->bitmap[i + 1], symbol->bitmap[i + 2]); + } + } + } + if (!postfix) { + putchar('\n'); + } else { + putchar('"'); + if (*postfix) { + fputs(postfix, stdout); } } - putchar('\n'); } - fputs(" ", stdout); - for (column = 0; column < symbol->bitmap_width; column++) printf("%d", column % 10); - fputs("\n ", stdout); - for (column = 0; column < symbol->bitmap_width; column += 10) printf("%-3d ", column); - putchar('\n'); + if (!postfix) { + fputs(" ", stdout); + for (column = 0; column < symbol->bitmap_width; column++) printf("%d", column % 10); + fputs("\n ", stdout); + for (column = 0; column < symbol->bitmap_width; column += 10) printf("%-3d ", column); + putchar('\n'); + } +} + +int testUtilBitmapCmp(const struct zint_symbol *symbol, const char *expected, int *row, int *column) { + static char colour[] = { '0', 'C', 'M', 'B', 'Y', 'G', 'R', '1' }; + int r, c, i, j; + const char *e = expected; + const char *ep = expected + strlen(expected); + char buf[7]; + + for (r = 0; r < symbol->bitmap_height; r++) { + for (c = 0; c < symbol->bitmap_width; c++) { + if (symbol->output_options & OUT_BUFFER_INTERMEDIATE) { + if (*e != symbol->bitmap[(r * symbol->bitmap_width) + c]) { + *row = r; + *column = c; + return 1 /*fail*/; + } + e++; + } else { + i = ((r * symbol->bitmap_width) + c) * 3; + if ((symbol->bitmap[i] == 0 || symbol->bitmap[i] == 0xff) && (symbol->bitmap[i + 1] == 0 || symbol->bitmap[i + 1] == 0xff) + && (symbol->bitmap[i + 2] == 0 || symbol->bitmap[i + 2] == 0xff)) { + j = (symbol->bitmap[i] == 0) + (symbol->bitmap[i + 1] == 0) * 2 + (symbol->bitmap[i + 2] == 0) * 4; + if (*e != colour[j]) { + *row = r; + *column = c; + return 1 /*fail*/; + } + e++; + } else { + sprintf(buf, "%02X%02X%02X", symbol->bitmap[i], symbol->bitmap[i + 1], symbol->bitmap[i + 2]); + if (strncmp(buf, e, 6) != 0) { + *row = r; + *column = c; + return 1 /*fail*/; + } + e += 6; + } + } + } + } + + *row = r; + *column = c; + return e != ep || r != symbol->bitmap_height || c != symbol->bitmap_width ? 1 /*fail*/ : 0 /*success*/; } int testUtilExists(char *filename) { diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 7b04b3dc..381f922f 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -73,6 +73,7 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size); #define ZINT_DEBUG_TEST_LESS_NOISY 32 #define ZINT_DEBUG_TEST_KEEP_OUTFILE 64 #define ZINT_DEBUG_TEST_BWIPP 128 +#define ZINT_DEBUG_TEST_PERFORMANCE 256 extern void vector_free(struct zint_symbol *symbol); /* Free vector structures */ @@ -90,14 +91,15 @@ void testUtilStrCpyRepeat(char *buffer, char *repeat, int size); int testUtilSymbolCmp(const struct zint_symbol *a, const struct zint_symbol *b); struct zint_vector *testUtilVectorCpy(const struct zint_vector *in); int testUtilVectorCmp(const struct zint_vector *a, const struct zint_vector *b); -void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix); // TODO: should be called Print not Dump -void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, char *prefix, char *postfix); // TODO: should be called Print not Dump +void testUtilModulesDump(const struct zint_symbol *symbol, const char *prefix, const char *postfix); // TODO: should be called Print not Dump +void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, const char *prefix, const char *postfix); // TODO: should be called Print not Dump int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, int *width, int *row); int testUtilModulesCmpRow(const struct zint_symbol *symbol, int row, const char *expected, int *width); int testUtilModulesDumpHex(const struct zint_symbol *symbol, char dump[], int dump_size); char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_size); char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dump_size); -void testUtilBitmapPrint(const struct zint_symbol *symbol); +void testUtilBitmapPrint(const struct zint_symbol *symbol, const char *prefix, const char *postfix); +int testUtilBitmapCmp(const struct zint_symbol *symbol, const char *expected, int *row, int *column); int testUtilExists(char *filename); int testUtilCmpPngs(char *file1, char *file2); int testUtilCmpTxts(char *txt1, char *txt2); diff --git a/backend/tif.c b/backend/tif.c index 0e296912..b02056be 100644 --- a/backend/tif.c +++ b/backend/tif.c @@ -43,7 +43,7 @@ #include #endif -INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { +INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { int fgred, fggrn, fgblu, bgred, bggrn, bgblu; int i; int rows_per_strip, strip_count; diff --git a/backend/tools/gen_pwr928_table.php b/backend/tools/gen_pwr928_table.php index 598e4ef1..59198d4e 100644 --- a/backend/tools/gen_pwr928_table.php +++ b/backend/tools/gen_pwr928_table.php @@ -35,7 +35,7 @@ for ($j = 1; $j < 69; $j++) { $pwr928[$j][0] = $cw[0] = (2 * $cw[0]) + (int)($v / 928); } -printf("static UINT pwr928[69][7] = {\n"); +printf("static const UINT pwr928[69][7] = {\n"); for ($i = 0; $i < 69; $i++) { printf(" { "); for ($j = 0; $j < 7; $j++) { diff --git a/backend/vector.c b/backend/vector.c index 4e9be76e..8e03a4e4 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -127,6 +127,7 @@ static int vector_plot_add_string(struct zint_symbol *symbol, struct zint_vector_string *string; string = (struct zint_vector_string*) malloc(sizeof (struct zint_vector_string)); + if (!string) return 0; string->next = NULL; string->x = x; string->y = y; @@ -136,6 +137,7 @@ static int vector_plot_add_string(struct zint_symbol *symbol, string->rotation = 0; string->halign = halign; string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1)); + if (!string->text) { free(string); return 0; } ustrcpy(string->text, text); if (*last_string) @@ -382,14 +384,14 @@ static void vector_reduce_rectangles(struct zint_symbol *symbol) { INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type) { int error_number; - int large_bar_height; + float large_bar_height; int textdone = 0; int main_width; int comp_offset = 0; unsigned char addon[6]; - int addon_gap; + int addon_gap = 0; float addon_text_posn = 0.0f; - float addon_bar_height; + float addon_bar_height = 0.0f; int xoffset, yoffset, roffset, boffset; float textoffset; float default_text_posn; @@ -401,7 +403,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ int hide_text; int i, r; int text_height; /* Font pixel size (so whole integers) */ - int upcae_outside_text_height; /* UPC-A/E outside digits font size */ + int upcae_outside_text_height = 0; /* UPC-A/E outside digits font size */ float digit_ascent_factor = 0.25f; /* Assuming digit ascent roughly 25% less than font size */ float text_gap; /* Gap between barcode and text */ float dot_overspill = 0.0f; @@ -540,41 +542,58 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ i = 0; - do { - int block_width = 0; + if (symbol->symbology == BARCODE_ULTRA) { do { - block_width++; - } while (i + block_width < symbol->width && module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); - if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { - addon_text_posn = row_posn + text_height - text_height * digit_ascent_factor; - if (addon_text_posn < 0.0f) { - addon_text_posn = 0.0f; - } - addon_bar_height = row_height - (addon_text_posn - row_posn) + text_gap; - if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E don't descend */ - addon_bar_height += 5.0f; - } - if (addon_bar_height < 0.5f) { - addon_bar_height = 0.5f; - } - addon_latch = 1; - } - if (module_is_set(symbol, this_row, i)) { - /* a bar or colour block */ - if (addon_latch == 0) { + int module_fill = module_colour_is_set(symbol, this_row, i); + int block_width = 0; + do { + block_width++; + } while (i + block_width < symbol->width && module_colour_is_set(symbol, this_row, i + block_width) == module_fill); + if (module_fill) { + /* a colour block */ rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height); - if (symbol->symbology == BARCODE_ULTRA) { - rectangle->colour = module_is_set(symbol, this_row, i); - } - } else { - rectangle = vector_plot_create_rect(i + xoffset, addon_text_posn - text_gap, block_width, addon_bar_height); + rectangle->colour = module_colour_is_set(symbol, this_row, i); + vector_plot_add_rect(symbol, rectangle, &last_rectangle); + rect_count++; } - vector_plot_add_rect(symbol, rectangle, &last_rectangle); - rect_count++; - } - i += block_width; + i += block_width; - } while (i < symbol->width); + } while (i < symbol->width); + } else { + do { + int module_fill = module_is_set(symbol, this_row, i); + int block_width = 0; + do { + block_width++; + } while (i + block_width < symbol->width && module_is_set(symbol, this_row, i + block_width) == module_fill); + if (upceanflag && (addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { + addon_text_posn = row_posn + text_height - text_height * digit_ascent_factor; + if (addon_text_posn < 0.0f) { + addon_text_posn = 0.0f; + } + addon_bar_height = row_height - (addon_text_posn - row_posn) + text_gap; + if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E don't descend */ + addon_bar_height += 5.0f; + } + if (addon_bar_height < 0.5f) { + addon_bar_height = 0.5f; + } + addon_latch = 1; + } + if (module_fill) { + /* a bar */ + if (addon_latch == 0) { + rectangle = vector_plot_create_rect(i + xoffset, row_posn, block_width, row_height); + } else { + rectangle = vector_plot_create_rect(i + xoffset, addon_text_posn - text_gap, block_width, addon_bar_height); + } + vector_plot_add_rect(symbol, rectangle, &last_rectangle); + rect_count++; + } + i += block_width; + + } while (i < symbol->width); + } row_posn += row_height; }