From a74871a7ded0aeeab75af8dc1bacfdbe89142c9b Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 3 Apr 2025 16:08:15 +0100 Subject: [PATCH] - CODABLOCKF: fix misencodation of extended ASCII 0xB0-0xB9 when followed by digit (ignore 2nd byte of FNC4 when categorizing Code C characters) - New `ZBarcode_Cap()` flag `ZINT_CAP_BINDABLE`, differentiated from `ZINT_CAP_STACKABLE`, and new Qt Backend method `isBindable()` - CLI: fix `separator` check to use new `ZINT_CAP_BINDABLE` instead of `ZINT_CAP_STACKABLE` - ZBarcode_Cap: add missing symbologies to `ZINT_CAP_BINDABLE` (was `ZINT_CAP_STACKABLE`) - DOTCODE: pad rows if given number of columns instead of failing if rows below min (5) - DBAR/composites: ensure stacked symbologies and composites are not stacked (set `symbol->rows` to 0) - test suite: move `test_perf` routines into single test "test_perf"; new "test_random" (based on "test_bwipp") to test various symbologies with random binary - discovered CODABLOCKF bug; expand "test_bwipp" manual: Feeback: mention AZTEC -1 meaning min & MICROPDF417: doc new `ZINT_CAP_BINDABLE` general: various code fiddlings and re-formattings --- ChangeLog | 13 +- backend/auspost.c | 9 +- backend/aztec.c | 12 +- backend/codablock.c | 109 +-- backend/code1.c | 24 +- backend/code128.c | 5 +- backend/code16k.c | 29 +- backend/code49.c | 12 +- backend/common.c | 9 +- backend/common.h | 3 +- backend/composite.c | 340 +++------ backend/dmatrix.c | 27 +- backend/dotcode.c | 23 +- backend/gridmtx.c | 174 ++--- backend/library.c | 36 +- backend/pdf417.c | 64 +- backend/plessey.c | 27 +- backend/qr.c | 23 +- backend/raster.c | 2 +- backend/rss.c | 113 +-- backend/tests/CMakeLists.txt | 2 + backend/tests/README | 14 +- backend/tests/test_2of5.c | 103 --- backend/tests/test_aztec.c | 117 ---- backend/tests/test_bwipp.c | 356 ++++++++-- backend/tests/test_codablock.c | 139 ++-- backend/tests/test_code.c | 105 --- backend/tests/test_code11.c | 101 --- backend/tests/test_code128.c | 334 +++++---- backend/tests/test_common.c | 62 +- backend/tests/test_composite.c | 91 --- backend/tests/test_dmatrix.c | 451 +++++------- backend/tests/test_dotcode.c | 94 +-- backend/tests/test_gridmtx.c | 87 --- backend/tests/test_gs1.c | 17 +- backend/tests/test_hanxin.c | 103 --- backend/tests/test_library.c | 693 ++++++++++++++---- backend/tests/test_maxicode.c | 103 --- backend/tests/test_output.c | 9 +- backend/tests/test_pdf417.c | 449 +++++------- backend/tests/test_perf.c | 718 +++++++++++++++++++ backend/tests/test_plessey.c | 103 --- backend/tests/test_postal.c | 102 --- backend/tests/test_qr.c | 849 +++++++++++------------ backend/tests/test_random.c | 301 ++++++++ backend/tests/test_upcean.c | 110 --- backend/tests/testcommon.c | 10 +- backend/tests/testcommon.h | 5 +- backend/tests/tools/bwipp_dump.ps.tar.xz | Bin 140144 -> 140192 bytes backend/vector.c | 2 +- backend/zint.h | 6 +- backend_qt/qzint.cpp | 4 + backend_qt/qzint.h | 1 + backend_qt/tests/test_qzint.cpp | 7 +- docs/manual.html | 23 +- docs/manual.pmd | 19 +- docs/manual.txt | 22 +- docs/zint.1 | 2 +- docs/zint.1.pmd | 2 +- frontend/main.c | 6 +- 60 files changed, 3509 insertions(+), 3267 deletions(-) create mode 100644 backend/tests/test_perf.c create mode 100644 backend/tests/test_random.c diff --git a/ChangeLog b/ChangeLog index 5916882f..8a704e12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Version 2.15.0.9 (dev) not released yet (2025-03-28) +Version 2.15.0.9 (dev) not released yet (2025-04-04) ==================================================== **Incompatible changes** @@ -8,6 +8,7 @@ Version 2.15.0.9 (dev) not released yet (2025-03-28) - Symbol structure members `option_1`, `option_2` and `option_3` now updated after `ZBarcode_Encode()` and variants are called, and there are three new methods in the Qt Backend to access to them +- New Qt Backend method `isBindable()` for new flag `ZINT_CAP_BINDABLE` - GS1 Composites now return warning if CC type upped from requested due to size of composite data @@ -25,12 +26,22 @@ Changes - composite: warn if CC type upped from requested - gs1: csumalpha: improve warning, report both chars (ticket #332, props Harald Oehlmann) +- New `ZBarcode_Cap()` flag `ZINT_CAP_BINDABLE`, differentiated from + `ZINT_CAP_STACKABLE`, and new Qt Backend method `isBindable()` +- DOTCODE: now pads rows if given number of columns instead of failing if rows + below min (5) Bugs ---- +- CODABLOCKF: fix misencodation of extended ASCII 0xB0-0xB9 when followed by + digit (ignore 2nd byte of FNC4 when categorizing Code C characters) - AZTEC: fix GS1 mode with Structured Append (wasn't outputting initial FNC1) - set_height: fix non-compliance false positives by using epsilon in checks - UPU_S10: fix Service Indicator warning re "H" (ticket #331, props Milton Neal) +- CLI: fix `separator` check to use new `ZINT_CAP_BINDABLE` instead of + `ZINT_CAP_STACKABLE` +- ZBarcode_Cap: add missing symbologies to `ZINT_CAP_BINDABLE` (was + `ZINT_CAP_STACKABLE`) - manual/man page: fix DATAMATRIX Sizes tables "28 12x26" -> "27 12x26" diff --git a/backend/auspost.c b/backend/auspost.c index 3b71d142..1d77b6b0 100644 --- a/backend/auspost.c +++ b/backend/auspost.c @@ -171,12 +171,9 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len } } else { switch (symbol->symbology) { - case BARCODE_AUSREPLY: memcpy(fcc, "45", 2); - break; - case BARCODE_AUSROUTE: memcpy(fcc, "87", 2); - break; - case BARCODE_AUSREDIRECT: memcpy(fcc, "92", 2); - break; + case BARCODE_AUSREPLY: memcpy(fcc, "45", 2); break; + case BARCODE_AUSROUTE: memcpy(fcc, "87", 2); break; + case BARCODE_AUSREDIRECT: memcpy(fcc, "92", 2); break; } /* Add leading zeros as required */ diff --git a/backend/aztec.c b/backend/aztec.c index 1150c094..935c9e60 100644 --- a/backend/aztec.c +++ b/backend/aztec.c @@ -887,6 +887,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int unsigned int *data_part; unsigned int *ecc_part; float ecc_ratio; + int dim; if (gs1 && reader_init) { return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 501, "Cannot use Reader Initialisation in GS1 mode"); @@ -1283,9 +1284,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int } symbol->row_height[y - offset] = 1; } - symbol->height = 27 - (2 * offset); - symbol->rows = 27 - (2 * offset); - symbol->width = 27 - (2 * offset); + dim = 27 - (2 * offset); } else { const int offset = AztecOffset[layers - 1]; const int end_offset = 151 - offset; @@ -1300,10 +1299,11 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int } symbol->row_height[y - offset] = 1; } - symbol->height = 151 - (2 * offset); - symbol->rows = 151 - (2 * offset); - symbol->width = 151 - (2 * offset); + dim = 151 - (2 * offset); } + symbol->height = dim; + symbol->rows = dim; + symbol->width = dim; return error_number; } diff --git a/backend/codablock.c b/backend/codablock.c index 8e9662a3..88253df8 100644 --- a/backend/codablock.c +++ b/backend/codablock.c @@ -72,10 +72,10 @@ typedef struct sCharacterSetTable { * The result is an OR of CodeA, CodeB, CodeC, CodeFNC1, CodeFNC4 depending on the * possible Code 128 character sets. */ -static int GetPossibleCharacterSet(unsigned char C) { +static int GetPossibleCharacterSet(const unsigned char C, const int prevNotFNC4) { if (C <= '\x1f') /* Control chars */ return CodeA; - if (z_isdigit(C)) + if (z_isdigit(C) && prevNotFNC4) return ZTNum; /* ZTNum = CodeA | CodeB | CodeC */ if (C == aFNC1) /* FNC1s (GS1) not used */ return ZTFNC1; /* ZTFNC1 = CodeA | CodeB | CodeC | CodeFNC1 */ /* Not reached */ @@ -93,37 +93,37 @@ static int GetPossibleCharacterSet(unsigned char C) { * int AFollowing, BFollowing The number of source characters you still may encode in this character set. * int CFollowing The number of characters encodable in CodeC if we start here. */ -static void CreateCharacterSetTable(CharacterSetTable T[], unsigned char *data, const int dataLength) { +static void CreateCharacterSetTable(CharacterSetTable T[], const unsigned char *data, const int dataLength) { int charCur; int runChar; + int prevNotFNC4; /* Treat the Data backwards */ charCur = dataLength - 1; - T[charCur].CharacterSet = GetPossibleCharacterSet(data[charCur]); - T[charCur].AFollowing = ((T[charCur].CharacterSet & CodeA) == 0) ? 0 : 1; - T[charCur].BFollowing = ((T[charCur].CharacterSet & CodeB) == 0) ? 0 : 1; - T[charCur].CFollowing = 0; + prevNotFNC4 = charCur > 0 ? data[charCur - 1] != aFNC4 : 1; + T[charCur].CharacterSet = GetPossibleCharacterSet(data[charCur], prevNotFNC4); + T[charCur].AFollowing = T[charCur].CharacterSet & CodeA ? 1 : 0; + T[charCur].BFollowing = T[charCur].CharacterSet & CodeB ? 1 : 0; for (charCur--; charCur >= 0; charCur--) { - T[charCur].CharacterSet = GetPossibleCharacterSet(data[charCur]); - T[charCur].AFollowing = ((T[charCur].CharacterSet & CodeA) == 0) ? 0 : T[charCur + 1].AFollowing + 1; - T[charCur].BFollowing = ((T[charCur].CharacterSet & CodeB) == 0) ? 0 : T[charCur + 1].BFollowing + 1; - T[charCur].CFollowing = 0; + prevNotFNC4 = charCur > 0 ? data[charCur - 1] != aFNC4 : 1; + T[charCur].CharacterSet = GetPossibleCharacterSet(data[charCur], prevNotFNC4); + T[charCur].AFollowing = T[charCur].CharacterSet & CodeA ? T[charCur + 1].AFollowing + 1 : 0; + T[charCur].BFollowing = T[charCur].CharacterSet & CodeB ? T[charCur + 1].BFollowing + 1 : 0; } /* Find the CodeC-chains */ for (charCur = 0; charCur < dataLength; charCur++) { T[charCur].CFollowing = 0; - if ((T[charCur].CharacterSet & CodeC) != 0) { + if (T[charCur].CharacterSet & CodeC) { /* CodeC possible */ runChar = charCur; do { /* Whether this is FNC1, whether next is */ /* numeric */ if (T[runChar].CharacterSet == ZTFNC1) /* FNC1s (GS1) not used */ - ++(T[charCur].CFollowing); /* Not reached */ + T[charCur].CFollowing++; /* Not reached */ else { - ++runChar; - if (runChar >= dataLength) + if (++runChar >= dataLength) break; /* Only a Number may follow */ if (T[runChar].CharacterSet == ZTNum) @@ -141,11 +141,9 @@ static void CreateCharacterSetTable(CharacterSetTable T[], unsigned char *data, * one bundle into the line (up to here). This is calculated online because * it depends on the space in the line. */ -static int RemainingDigits(CharacterSetTable *T, int charCur, int emptyColumns) { - int digitCount; /* Numerical digits fitting in the line */ - int runChar; - runChar = charCur; - digitCount = 0; +static int RemainingDigits(const CharacterSetTable T[], const int charCur, int emptyColumns) { + int digitCount = 0; /* Numerical digits fitting in the line */ + int runChar = charCur; while (emptyColumns > 0 && runChar < charCur + T[charCur].CFollowing) { if (T[runChar].CharacterSet != ZTFNC1) { /* NOT FNC1 */ @@ -168,8 +166,8 @@ static int RemainingDigits(CharacterSetTable *T, int charCur, int emptyColumns) * pSet Output of the character sets used, allocated by me. * Return value Resulting row count */ -static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength, int *pRows, - int *pUseColumns, int *pSet, int *pFillings) { +static int Columns2Rows(const CharacterSetTable T[], const int dataLength, int *pRows, int *pUseColumns, int *pSet, + int *pFillings, const int debug) { int useColumns; /* Usable Characters per line */ int fillings = 0; /* Number of filling characters */ int rowsCur; @@ -191,7 +189,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const /* >>> Line Loop */ do { /* >> Start Character */ - emptyColumns = useColumns; /* Remained place in Line */ + emptyColumns = useColumns; /* Remaining space in line */ /* >>Choose in Set A or B */ /* (C is changed as an option later on) */ @@ -226,7 +224,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const /* >> Following characters */ while (emptyColumns > 0 && charCur < dataLength) { - isFNC4 = (T[charCur].CharacterSet & CodeFNC4); + isFNC4 = T[charCur].CharacterSet & CodeFNC4; switch (characterSetCur) { case CodeA: case CodeB: @@ -342,13 +340,18 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const switch (emptyColumns) { case 1: pSet[charCur - 1] |= CFill; - /* fall through */ + /* [[fallthrough]] */ case 0: ++rowsCur; fillings = useColumns - 2 + emptyColumns; break; - case 2: fillings = 0; break; - default: pSet[charCur - 1] |= CFill; fillings = emptyColumns - 2; + case 2: + fillings = 0; + break; + default: + pSet[charCur - 1] |= CFill; + fillings = emptyColumns - 2; + break; } if (rowsCur > 44) { @@ -361,7 +364,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const fillings += useColumns; } } while (rowsCur > 44); - if (symbol->debug & ZINT_DEBUG_PRINT) { + if (debug) { printf(" -> out: rowsCur <%d>, useColumns <%d>, fillings <%d>\n", rowsCur, useColumns, fillings); } *pUseColumns = useColumns; @@ -372,8 +375,8 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const /* Find columns if row count is given. */ -static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength, int *pRows, - int *pUseColumns, int *pSet, int *pFillings) { +static int Rows2Columns(const CharacterSetTable T[], const int dataLength, int *pRows, int *pUseColumns, int *pSet, + int *pFillings, const int debug) { int rowsCur; int rowsRequested; /* Number of requested rows */ int columnsRequested; /* Number of requested columns (if any) */ @@ -387,7 +390,7 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const rowsRequested = *pRows; columnsRequested = *pUseColumns >= 4 ? *pUseColumns : 0; - if (symbol->debug & ZINT_DEBUG_PRINT) { + if (debug) { printf("Optimizer : Searching <%d> rows\n", rowsRequested); } @@ -407,7 +410,7 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const pTestList[testListSize] = testColumns; testListSize++; useColumns = testColumns; /* Make a copy because it may be modified */ - errorCur = Columns2Rows(symbol, T, dataLength, &rowsCur, &useColumns, pSet, &fillings); + errorCur = Columns2Rows(T, dataLength, &rowsCur, &useColumns, pSet, &fillings, debug); if (errorCur != 0) return errorCur; if (rowsCur <= rowsRequested) { @@ -448,7 +451,7 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const /* Print a character in character set A */ -static void A2C128_A(uchar **ppOutPos, uchar c) { +static void A2C128_A(uchar **ppOutPos, const uchar c) { uchar *pOutPos = *ppOutPos; switch (c) { case aCodeB: *pOutPos = 100; break; @@ -471,7 +474,7 @@ static void A2C128_A(uchar **ppOutPos, uchar c) { /* Output c in Set B */ -static void A2C128_B(uchar **ppOutPos, uchar c) { +static void A2C128_B(uchar **ppOutPos, const uchar c) { uchar *pOutPos = *ppOutPos; switch (c) { case aFNC1: *pOutPos = 102; break; /* FNC1s (GS1) not used */ /* Not reached */ @@ -483,12 +486,12 @@ static void A2C128_B(uchar **ppOutPos, uchar c) { case aShift: *pOutPos = 98; break; default: *pOutPos = (uchar) (c - ' '); break; } - ++(*ppOutPos); + (*ppOutPos)++; } /* Output c1, c2 in Set C */ -static void A2C128_C(uchar **ppOutPos, uchar c1, uchar c2) { +static void A2C128_C(uchar **ppOutPos, const uchar c1, const uchar c2) { uchar *pOutPos = *ppOutPos; switch (c1) { case aFNC1: *pOutPos = 102; break; /* FNC1s (GS1) not used */ /* Not reached */ @@ -501,7 +504,7 @@ static void A2C128_C(uchar **ppOutPos, uchar c1, uchar c2) { /* Output a character in Characterset */ -static void ASCIIZ128(uchar **ppOutPos, int CharacterSet, uchar c1, uchar c2) { +static void ASCIIZ128(uchar **ppOutPos, const int CharacterSet, const uchar c1, const uchar c2) { if (CharacterSet == CodeA) A2C128_A(ppOutPos, c1); else if (CharacterSet == CodeB) @@ -512,7 +515,7 @@ static void ASCIIZ128(uchar **ppOutPos, int CharacterSet, uchar c1, uchar c2) { /* XLate Tables D.2, D.3 and F.1 of Codablock-F Specification and call output */ -static void SumASCII(uchar **ppOutPos, int Sum, int CharacterSet) { +static void SumASCII(uchar **ppOutPos, const int Sum, const int CharacterSet) { switch (CharacterSet) { case CodeA: /* Row # Indicators and Data Check Characters K1/K2 for CodeA and CodeB are the same */ case CodeB: @@ -548,6 +551,7 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int int *pSet; uchar *pOutput; const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; + const int debug = symbol->debug & ZINT_DEBUG_PRINT; /* Suppresses clang-analyzer-core.VLASize warning */ assert(length > 0); @@ -595,18 +599,15 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int dataLength = 0; if (symbol->output_options & READER_INIT) { - data[dataLength] = aFNC3; - dataLength++; + data[dataLength++] = aFNC3; } /* Replace all Codes>127 with Code-128 */ for (charCur = 0; charCur < length; charCur++) { if (source[charCur] > 127) { - data[dataLength] = aFNC4; - dataLength++; - data[dataLength] = (unsigned char) (source[charCur] & 127); + data[dataLength++] = aFNC4; + data[dataLength++] = (unsigned char) (source[charCur] & 127); } else - data[dataLength] = source[charCur]; - dataLength++; + data[dataLength++] = source[charCur]; } /* Build character set table */ @@ -625,7 +626,7 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int } else if (columns < 9) { columns = 9; } - if (symbol->debug & ZINT_DEBUG_PRINT) { + if (debug) { printf("Auto column count for %d characters:%d\n", dataLength, columns); } } @@ -633,10 +634,10 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int useColumns = columns - 5; if (rows > 0) { /* Row count given */ - error_number = Rows2Columns(symbol, T, dataLength, &rows, &useColumns, pSet, &fillings); + error_number = Rows2Columns(T, dataLength, &rows, &useColumns, pSet, &fillings, debug); } else { /* Column count given */ - error_number = Columns2Rows(symbol, T, dataLength, &rows, &useColumns, pSet, &fillings); + error_number = Columns2Rows(T, dataLength, &rows, &useColumns, pSet, &fillings, debug); } if (error_number != 0) { return errtxt(error_number, symbol, 413, @@ -652,7 +653,7 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int Sum2 = (Sum2 + charCur * source[charCur]) % 86; } - if (symbol->debug & ZINT_DEBUG_PRINT) { + if (debug) { int DPos; fputs("\nData:", stdout); for (DPos = 0; DPos < dataLength; DPos++) @@ -745,24 +746,24 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int while (emptyColumns > 0 && charCur < dataLength) { /* ? Change character set */ if (emptyColumns < useColumns) { - if ((pSet[charCur] & CodeA) != 0) { + if (pSet[charCur] & CodeA) { /* Change to A */ ASCIIZ128(&pOutPos, characterSetCur, aCodeA, '\0'); --emptyColumns; characterSetCur = CodeA; - } else if ((pSet[charCur] & CodeB) != 0) { + } else if (pSet[charCur] & CodeB) { /* Change to B */ ASCIIZ128(&pOutPos, characterSetCur, aCodeB, '\0'); --emptyColumns; characterSetCur = CodeB; - } else if ((pSet[charCur] & CodeC) != 0) { + } else if (pSet[charCur] & CodeC) { /* Change to C */ ASCIIZ128(&pOutPos, characterSetCur, aCodeC, '\0'); --emptyColumns; characterSetCur = CodeC; } } - if ((pSet[charCur] & CShift) != 0) { + if (pSet[charCur] & CShift) { /* >> Shift it and put out the shifted character */ ASCIIZ128(&pOutPos, characterSetCur, aShift, '\0'); emptyColumns -= 2; @@ -832,7 +833,7 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int *pOutPos++ = 106; } /* End Lineloop */ - if (symbol->debug & ZINT_DEBUG_PRINT) { + if (debug) { int DPos, DPos2; fputs("\nCode 128 Code Numbers:\n", stdout); for (DPos = 0; DPos < rows; DPos++) { diff --git a/backend/code1.c b/backend/code1.c index 86fdebf9..da28bee0 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -195,14 +195,10 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co } switch (current_mode) { - case C1_C40: c40_count = 0; /* Step J2 */ - break; - case C1_TEXT: text_count = 0; /* Step J3 */ - break; - case C1_EDI: edi_count = 0; /* Missing in spec */ - break; - case C1_BYTE: byte_count = 0; /* Step J4 */ - break; + case C1_C40: c40_count = 0; break; /* Step J2 */ + case C1_TEXT: text_count = 0; break; /* Step J3 */ + case C1_EDI: edi_count = 0; break; /* Missing in spec */ + case C1_BYTE: byte_count = 0; break; /* Step J4 */ } for (sp = position; sp < length; sp++) { @@ -579,16 +575,20 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len if (current_mode != next_mode) { /* Change mode */ switch (next_mode) { - case C1_C40: target[tp++] = 230; + case C1_C40: + target[tp++] = 230; if (debug_print) fputs("->C40 ", stdout); break; - case C1_TEXT: target[tp++] = 239; + case C1_TEXT: + target[tp++] = 239; if (debug_print) fputs("->Text ", stdout); break; - case C1_EDI: target[tp++] = 238; + case C1_EDI: + target[tp++] = 238; if (debug_print) fputs("->EDI ", stdout); break; - case C1_BYTE: target[tp++] = 231; + case C1_BYTE: + target[tp++] = 231; if (debug_print) fputs("->Byte ", stdout); byte_start = tp; target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */ diff --git a/backend/code128.c b/backend/code128.c index f3dddbea..d987ec9a 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -525,9 +525,8 @@ INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int /* If part of a composite symbol make room for the separator pattern */ if (symbol->symbology == BARCODE_GS1_128_CC) { - separator_row = symbol->rows; - symbol->row_height[symbol->rows] = 1; - symbol->rows += 1; + separator_row = symbol->rows++; + symbol->row_height[separator_row] = 1; } error_number = gs1_verify(symbol, source, length, reduced, &reduced_length); diff --git a/backend/code16k.c b/backend/code16k.c index d2b8cb0f..f85c79c7 100644 --- a/backend/code16k.c +++ b/backend/code16k.c @@ -134,7 +134,7 @@ static void c16k_dxsmooth(int list[2][C128_MAX], int *p_indexliste) { } } - if (i == 0) { /* first block */ + if (i == 0) { /* First block */ if (current == C16K_ABORC) { if ((indexliste == 1) && (length == 2)) { /* Rule 1a */ @@ -383,16 +383,8 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len printf("FSet: %.*s\n", length, fset); } - /* start with the mode character - Table 2 */ - m = 0; - switch (set[0]) { - case 'A': m = 0; - break; - case 'B': m = 1; - break; - case 'C': m = 2; - break; - } + /* Start with the mode character - Table 2 */ + m = set[0] - 'A'; if (symbol->output_options & READER_INIT) { if (gs1) { @@ -409,10 +401,8 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len if (gs1) { /* Integrate FNC1 */ switch (set[0]) { - case 'B': m = 3; - break; - case 'C': m = 4; - break; + case 'B': m = 3; break; + case 'C': m = 4; break; } } else { if ((set[0] == 'B') && (set[1] == 'C')) { @@ -472,14 +462,17 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len if (!gs1 || source[read] != '\x1D') { switch (set[read]) { /* Encode data characters */ case 'A': - case 'a': c16k_set_a(source[read], values, &bar_characters); + case 'a': + c16k_set_a(source[read], values, &bar_characters); read++; break; case 'B': - case 'b': (void) c16k_set_b(source[read], values, &bar_characters); + case 'b': + (void) c16k_set_b(source[read], values, &bar_characters); read++; break; - case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters); + case 'C': + c16k_set_c(source[read], source[read + 1], values, &bar_characters); read += 2; break; } diff --git a/backend/code49.c b/backend/code49.c index 4bd17af5..989418ef 100644 --- a/backend/code49.c +++ b/backend/code49.c @@ -201,14 +201,10 @@ INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int leng switch (codewords[0]) { /* Set starting mode value */ - case 48: M = 2; - break; - case 43: M = 4; - break; - case 44: M = 5; - break; - default: M = 0; - break; + case 48: M = 2; break; + case 43: M = 4; break; + case 44: M = 5; break; + default: M = 0; break; } if (M != 0) { diff --git a/backend/common.c b/backend/common.c index 3053a85c..6ec8851b 100644 --- a/backend/common.c +++ b/backend/common.c @@ -535,7 +535,7 @@ INTERNAL int errtxt_adj(const int error_number, struct zint_symbol *symbol, cons } /* Whether `symbology` can have row binding */ -INTERNAL int is_stackable(const int symbology) { +INTERNAL int is_bindable(const int symbology) { if (symbology < BARCODE_PHARMA_TWO && symbology != BARCODE_POSTNET) { return 1; } @@ -544,6 +544,7 @@ INTERNAL int is_stackable(const int symbology) { case BARCODE_CODE128AB: case BARCODE_ISBNX: case BARCODE_EAN14: + case BARCODE_VIN: case BARCODE_NVE18: case BARCODE_KOREAPOST: case BARCODE_PLESSEY: @@ -551,7 +552,13 @@ INTERNAL int is_stackable(const int symbology) { case BARCODE_ITF14: case BARCODE_CODE32: case BARCODE_CODABLOCKF: + case BARCODE_DPD: + case BARCODE_HIBC_128: + case BARCODE_HIBC_39: case BARCODE_HIBC_BLOCKF: + case BARCODE_UPU_S10: + case BARCODE_CHANNEL: + case BARCODE_BC412: return 1; break; } diff --git a/backend/common.h b/backend/common.h index 1002ed56..2180790f 100644 --- a/backend/common.h +++ b/backend/common.h @@ -206,7 +206,6 @@ INTERNAL int posn(const char set_string[], const char data); `bin_posn`. Returns `bin_posn` + `length` */ INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn); - #define Z_COMMON_INLINE 1 #ifdef Z_COMMON_INLINE @@ -267,7 +266,7 @@ INTERNAL int errtxt_adj(const int error_number, struct zint_symbol *symbol, cons /* Whether `symbology` can have row binding */ -INTERNAL int is_stackable(const int symbology); +INTERNAL int is_bindable(const int symbology); /* Whether `symbology` is EAN/UPC */ INTERNAL int is_upcean(const int symbology); diff --git a/backend/composite.c b/backend/composite.c index b43931b0..cd231207 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -80,12 +80,12 @@ static int cc_min(const int first, const int second) { return second; } -/* gets bit in bitString at bitPos */ +/* Gets bit in bitString at bitPos */ static int cc_getBit(const unsigned short *bitStr, const int bitPos) { return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15))); } -/* converts bit string to base 928 values, codeWords[0] is highest order */ +/* Converts bit string to base 928 values, codeWords[0] is highest order */ static int cc_encode928(const unsigned short bitString[], unsigned short codeWords[], const int bitLng) { int i, j, b, cwNdx, cwLng; for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) { @@ -101,7 +101,7 @@ static int cc_encode928(const unsigned short bitString[], unsigned short codeWor } } for (i = cwCnt - 1; i > 0; i--) { - /* add "carries" */ + /* Add "carries" */ codeWords[cwNdx + i - 1] += codeWords[cwNdx + i] / 928; codeWords[cwNdx + i] %= 928; } @@ -111,7 +111,7 @@ static int cc_encode928(const unsigned short bitString[], unsigned short codeWor /* CC-A 2D component */ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_width) { - int i, segment, bitlen, cwCnt, variant, rows; + int i, segment, bitlen, cwCnt, variant; int k, offset, j, total, rsCodeWords[8] = {0}; int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; int LeftRAP, RightRAP, CentreRAP, Cluster; @@ -138,59 +138,42 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w } } - /* encode codeWords from bitStr */ + /* Encode codeWords from bitStr */ cwCnt = cc_encode928(bitStr, codeWords, bitlen); switch (cc_width) { case 2: switch (cwCnt) { - case 6: variant = 0; - break; - case 8: variant = 1; - break; - case 9: variant = 2; - break; - case 11: variant = 3; - break; - case 12: variant = 4; - break; - case 14: variant = 5; - break; - case 17: variant = 6; - break; + case 6: variant = 0; break; + case 8: variant = 1; break; + case 9: variant = 2; break; + case 11: variant = 3; break; + case 12: variant = 4; break; + case 14: variant = 5; break; + case 17: variant = 6; break; } break; case 3: switch (cwCnt) { - case 8: variant = 7; - break; - case 10: variant = 8; - break; - case 12: variant = 9; - break; - case 14: variant = 10; - break; - case 17: variant = 11; - break; + case 8: variant = 7; break; + case 10: variant = 8; break; + case 12: variant = 9; break; + case 14: variant = 10; break; + case 17: variant = 11; break; } break; case 4: switch (cwCnt) { - case 8: variant = 12; - break; - case 11: variant = 13; - break; - case 14: variant = 14; - break; - case 17: variant = 15; - break; - case 20: variant = 16; - break; + case 8: variant = 12; break; + case 11: variant = 13; break; + case 14: variant = 14; break; + case 17: variant = 15; break; + case 20: variant = 16; break; } break; } - rows = cc_aVariants[variant]; + symbol->rows = cc_aVariants[variant]; k = cc_aVariants[17 + variant]; offset = cc_aVariants[34 + variant]; @@ -229,7 +212,7 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w RightRAP = RightRAPStart; Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ - for (i = 0; i < rows; i++) { + for (i = 0; i < symbol->rows; i++) { bp = 0; offset = 929 * Cluster; k = i * cc_width; @@ -258,16 +241,15 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w } } bp = bin_append_posn(pdf_rap_side[RightRAP - 1], 10, pattern, bp); - pattern[bp++] = '1'; /* stop */ + pattern[bp++] = '1'; /* Stop */ - /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + /* So now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ for (loop = 0; loop < bp; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); } } symbol->row_height[i] = 2; - symbol->rows++; /* Set up RAPs and Cluster for next row */ LeftRAP++; @@ -400,10 +382,10 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w assert(variant >= 0); columns = pdf_MicroVariants[variant]; /* columns */ symbol->rows = pdf_MicroVariants[variant + 34]; /* rows */ - k = pdf_MicroVariants[variant + 68]; /* number of EC CWs */ - longueur = (columns * symbol->rows) - k; /* number of non-EC CWs */ - i = longueur - mclength; /* amount of padding required */ - offset = pdf_MicroVariants[variant + 102]; /* coefficient offset */ + k = pdf_MicroVariants[variant + 68]; /* Number of EC CWs */ + longueur = (columns * symbol->rows) - k; /* Number of non-EC CWs */ + i = longueur - mclength; /* Amount of padding required */ + offset = pdf_MicroVariants[variant + 102]; /* Coefficient offset */ /* Binary input padded to target length so no padding should be necessary */ while (i > 0) { @@ -429,7 +411,7 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w mccorrection[j] = 929 - mccorrection[j]; } } - /* we add these codes to the string */ + /* We add these codes to the string */ for (i = k - 1; i >= 0; i--) { chainemc[mclength++] = mccorrection[i]; } @@ -475,9 +457,9 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w } } bp = bin_append_posn(pdf_rap_side[RightRAP - 1], 10, pattern, bp); - pattern[bp++] = '1'; /* stop */ + pattern[bp++] = '1'; /* Stop */ - /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + /* So now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ for (loop = 0; loop < bp; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); @@ -536,7 +518,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w } } - chainemc[mclength++] = 0; /* space for length descriptor */ + chainemc[mclength++] = 0; /* Space for length descriptor */ chainemc[mclength++] = 920; /* CC-C identifier */ pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0); @@ -556,24 +538,15 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w /* 796 - we now take care of the Reed Solomon codes */ switch (ecc_level) { - case 1: offset = 2; /* Not reached */ - break; - case 2: offset = 6; /* Min ECC currently used is 2 */ - break; - case 3: offset = 14; - break; - case 4: offset = 30; - break; - case 5: offset = 62; /* Max ECC currently used is 5 */ - break; - case 6: offset = 126; /* Not reached */ - break; - case 7: offset = 254; /* Not reached */ - break; - case 8: offset = 510; /* Not reached */ - break; - default: offset = 0; /* Not reached */ - break; + case 1: offset = 2; break; /* Not reached */ + case 2: offset = 6; break; /* Min ECC currently used is 2 */ + case 3: offset = 14; break; + case 4: offset = 30; break; + case 5: offset = 62; break; /* Max ECC currently used is 5 */ + case 6: offset = 126; break; /* Not reached */ + case 7: offset = 254; break; /* Not reached */ + case 8: offset = 510; break; /* Not reached */ + default: offset = 0; break; /* Not reached */ } longueur = mclength; @@ -593,7 +566,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w mccorrection[j] = 929 - mccorrection[j]; } } - /* we add these codes to the string */ + /* We add these codes to the string */ for (i = k - 1; i >= 0; i--) { chainemc[mclength++] = mccorrection[i]; } @@ -604,7 +577,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w c2 = ecc_level * 3 + (symbol->rows - 1) % 3; c3 = cc_width - 1; - /* we now encode each row */ + /* We now encode each row */ for (i = 0; i <= symbol->rows - 1; i++) { for (j = 0; j < cc_width; j++) { dummy[j + 1] = chainemc[i * cc_width + j]; @@ -652,126 +625,40 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w } static int cc_a_calc_padding(const int binary_length, const int cc_width) { + static const short bin_lens[3][7] = { + { 59, 78, 88, 108, 118, 138, 167 }, + { 78, 98, 118, 138, 167, 0, 0 }, + { 78, 108, 138, 167, 197, 0, 0 }, + }; + const short *bin_len = bin_lens[cc_width - 2]; int target_bitsize = 0; + int i; - switch (cc_width) { - case 2: - if (binary_length <= 59) { - target_bitsize = 59; - } else if (binary_length <= 78) { - target_bitsize = 78; - } else if (binary_length <= 88) { - target_bitsize = 88; - } else if (binary_length <= 108) { - target_bitsize = 108; - } else if (binary_length <= 118) { - target_bitsize = 118; - } else if (binary_length <= 138) { - target_bitsize = 138; - } else if (binary_length <= 167) { - target_bitsize = 167; - } - break; - case 3: - if (binary_length <= 78) { - target_bitsize = 78; - } else if (binary_length <= 98) { - target_bitsize = 98; - } else if (binary_length <= 118) { - target_bitsize = 118; - } else if (binary_length <= 138) { - target_bitsize = 138; - } else if (binary_length <= 167) { - target_bitsize = 167; - } - break; - case 4: - if (binary_length <= 78) { - target_bitsize = 78; - } else if (binary_length <= 108) { - target_bitsize = 108; - } else if (binary_length <= 138) { - target_bitsize = 138; - } else if (binary_length <= 167) { - target_bitsize = 167; - } else if (binary_length <= 197) { - target_bitsize = 197; - } + for (i = 0; i < ARRAY_SIZE(bin_lens[0]) && bin_len[i]; i++) { + if (binary_length <= bin_len[i]) { + target_bitsize = bin_len[i]; break; + } } return target_bitsize; } static int cc_b_calc_padding(const int binary_length, const int cc_width) { + static const short bin_lens[3][11] = { + { 56, 104, 160, 208, 256, 296, 336, 0, 0, 0, 0 }, + { 32, 72, 112, 152, 208, 304, 416, 536, 648, 768, 0 }, + { 56, 96, 152, 208, 264, 352, 496, 672, 840, 1016, 1184 }, + }; + const short *bin_len = bin_lens[cc_width - 2]; int target_bitsize = 0; + int i; - switch (cc_width) { - case 2: - if (binary_length <= 56) { - target_bitsize = 56; - } else if (binary_length <= 104) { - target_bitsize = 104; - } else if (binary_length <= 160) { - target_bitsize = 160; - } else if (binary_length <= 208) { - target_bitsize = 208; - } else if (binary_length <= 256) { - target_bitsize = 256; - } else if (binary_length <= 296) { - target_bitsize = 296; - } else if (binary_length <= 336) { - target_bitsize = 336; - } - break; - case 3: - if (binary_length <= 32) { - target_bitsize = 32; - } else if (binary_length <= 72) { - target_bitsize = 72; - } else if (binary_length <= 112) { - target_bitsize = 112; - } else if (binary_length <= 152) { - target_bitsize = 152; - } else if (binary_length <= 208) { - target_bitsize = 208; - } else if (binary_length <= 304) { - target_bitsize = 304; - } else if (binary_length <= 416) { - target_bitsize = 416; - } else if (binary_length <= 536) { - target_bitsize = 536; - } else if (binary_length <= 648) { - target_bitsize = 648; - } else if (binary_length <= 768) { - target_bitsize = 768; - } - break; - case 4: - if (binary_length <= 56) { - target_bitsize = 56; - } else if (binary_length <= 96) { - target_bitsize = 96; - } else if (binary_length <= 152) { - target_bitsize = 152; - } else if (binary_length <= 208) { - target_bitsize = 208; - } else if (binary_length <= 264) { - target_bitsize = 264; - } else if (binary_length <= 352) { - target_bitsize = 352; - } else if (binary_length <= 496) { - target_bitsize = 496; - } else if (binary_length <= 672) { - target_bitsize = 672; - } else if (binary_length <= 840) { - target_bitsize = 840; - } else if (binary_length <= 1016) { - target_bitsize = 1016; - } else if (binary_length <= 1184) { - target_bitsize = 1184; - } + for (i = 0; i < ARRAY_SIZE(bin_lens[0]) && bin_len[i]; i++) { + if (binary_length <= bin_len[i]) { + target_bitsize = bin_len[i]; break; + } } return target_bitsize; @@ -820,7 +707,7 @@ static int cc_c_calc_padding(const int binary_length, int *p_cc_width, const int } assert(*p_cc_width > 0); rows = (int) ceil((double) codewords_used / *p_cc_width); - /* stop the symbol from becoming too high */ + /* Stop the symbol from becoming too high */ while (rows > 30 && *p_cc_width < 30) { (*p_cc_width)++; rows = (int) ceil((double) codewords_used / *p_cc_width); @@ -967,7 +854,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour } } - /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */ + /* Must start with 0, 1, 2 or 3 digits followed by an uppercase character */ alpha_posn = -1; if (ninety_len && ninety[0] != '0') { /* Leading zeros are not permitted */ for (i = 0; i < ninety_len && i < 4; i++) { @@ -1028,12 +915,15 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour } switch (ai_crop) { - case 0: binary_string[bp++] = '0'; + case 0: + binary_string[bp++] = '0'; break; - case 1: bp = bin_append_posn(2, 2, binary_string, bp); /* "10" */ + case 1: + bp = bin_append_posn(2, 2, binary_string, bp); /* "10" */ ai_crop_posn = next_ai_posn + 1; break; - case 3: bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ + case 3: + bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ ai_crop_posn = next_ai_posn + 1; break; } @@ -1050,7 +940,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour /* five bit binary string representing value before letter */ bp = bin_append_posn(numeric_value, 5, binary_string, bp); - /* followed by four bit representation of letter from Table 3 */ + /* Followed by four bit representation of letter from Table 3 */ bp = bin_append_posn(table3_letter, 4, binary_string, bp); } else { /* Encoding is done according to 5.3.2 c) 3) */ @@ -1169,15 +1059,9 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour } switch (cc_mode) { - case 1: - target_bitsize = cc_a_calc_padding(bp, *p_cc_width); - break; - case 2: - target_bitsize = cc_b_calc_padding(bp, *p_cc_width); - break; - case 3: - target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level); - break; + case 1: target_bitsize = cc_a_calc_padding(bp, *p_cc_width); break; + case 2: target_bitsize = cc_b_calc_padding(bp, *p_cc_width); break; + case 3: target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level); break; } if (target_bitsize == 0) { @@ -1313,24 +1197,15 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 449, "Input length %d wrong (linear component)", pri_len); } break; - case BARCODE_GS1_128_CC: cc_width = 4; - break; - case BARCODE_DBAR_OMN_CC: cc_width = 4; - break; - case BARCODE_DBAR_LTD_CC: cc_width = 3; - break; - case BARCODE_DBAR_EXP_CC: cc_width = 4; - break; - case BARCODE_UPCA_CC: cc_width = 4; - break; - case BARCODE_UPCE_CC: cc_width = 2; - break; - case BARCODE_DBAR_STK_CC: cc_width = 2; - break; - case BARCODE_DBAR_OMNSTK_CC: cc_width = 2; - break; - case BARCODE_DBAR_EXPSTK_CC: cc_width = 4; - break; + case BARCODE_GS1_128_CC: cc_width = 4; break; + case BARCODE_DBAR_OMN_CC: cc_width = 4; break; + case BARCODE_DBAR_LTD_CC: cc_width = 3; break; + case BARCODE_DBAR_EXP_CC: cc_width = 4; break; + case BARCODE_UPCA_CC: cc_width = 4; break; + case BARCODE_UPCE_CC: cc_width = 2; break; + case BARCODE_DBAR_STK_CC: cc_width = 2; break; + case BARCODE_DBAR_OMNSTK_CC: cc_width = 2; break; + case BARCODE_DBAR_EXPSTK_CC: cc_width = 4; break; } if (cc_mode < 1 || cc_mode > 3) { @@ -1369,14 +1244,14 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l } } + symbol->rows = 0; /* Composites are not stackable */ + switch (cc_mode) { - /* Note that ecc_level is only relevant to CC-C */ - case 1: cc_a(symbol, binary_string, cc_width); - break; - case 2: cc_b(symbol, binary_string, cc_width); - break; - case 3: cc_c(symbol, binary_string, cc_width, ecc_level); - break; + /* Note that ecc_level is only relevant to CC-C */ + case 1: cc_a(symbol, binary_string, cc_width); break; + case 2: cc_b(symbol, binary_string, cc_width); break; + case 3: cc_c(symbol, binary_string, cc_width, ecc_level); break; + default: assert(0); break; /* Not reached */ } if (symbol->option_1 >= 1 && symbol->option_1 <= 3 && symbol->option_1 != cc_mode) { @@ -1497,7 +1372,8 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l } } break; - case BARCODE_DBAR_OMN_CC: bottom_shift = 4; + case BARCODE_DBAR_OMN_CC: + bottom_shift = 4; break; case BARCODE_DBAR_LTD_CC: if (cc_mode == 1) { @@ -1510,13 +1386,17 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l for (k = 1; !module_is_set(linear, 1, k - 1) && module_is_set(linear, 1, k); k++); top_shift = k; break; - case BARCODE_UPCA_CC: bottom_shift = 2; + case BARCODE_UPCA_CC: + bottom_shift = 2; break; - case BARCODE_UPCE_CC: bottom_shift = 2; + case BARCODE_UPCE_CC: + bottom_shift = 2; break; - case BARCODE_DBAR_STK_CC: top_shift = 1; + case BARCODE_DBAR_STK_CC: + top_shift = 1; break; - case BARCODE_DBAR_OMNSTK_CC: top_shift = 1; + case BARCODE_DBAR_OMNSTK_CC: + top_shift = 1; break; case BARCODE_DBAR_EXPSTK_CC: for (k = 1; !module_is_set(linear, 1, k - 1) && module_is_set(linear, 1, k); k++); @@ -1530,7 +1410,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l if (top_shift != 0) { /* Move the 2D component of the symbol horizontally */ - for (i = 0; i <= symbol->rows; i++) { + for (i = 0; i < symbol->rows; i++) { for (j = (symbol->width + top_shift); j >= top_shift; j--) { if (module_is_set(symbol, i, j - top_shift)) { set_module(symbol, i, j); @@ -1545,7 +1425,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l } /* Merge linear and 2D components into one structure */ - for (i = 0; i <= linear->rows; i++) { + for (i = 0; i < linear->rows; i++) { symbol->row_height[symbol->rows + i] = linear->row_height[i]; for (j = 0; j <= linear->width; j++) { if (module_is_set(linear, i, j)) { @@ -1569,15 +1449,15 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l /* If symbol->height given then min row height was returned, else default height */ if (error_number == 0) { /* Avoid overwriting any `gs1_verify()` warning */ error_number = set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); } else { (void) set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/); } } else { /* If symbol->height given then min row height was returned, else default height */ error_number = set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); } } else { if (symbol->symbology == BARCODE_DBAR_STK_CC) { diff --git a/backend/dmatrix.c b/backend/dmatrix.c index a91a2a10..1f1f14b7 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -306,14 +306,10 @@ static int dm_look_ahead_test(const unsigned char source[], const int length, co } switch (current_mode) { - case DM_C40: c40_count = 0; - break; - case DM_TEXT: text_count = 0; - break; - case DM_X12: x12_count = 0; - break; - case DM_EDIFACT: edf_count = 0; - break; + case DM_C40: c40_count = 0; break; + case DM_TEXT: text_count = 0; break; + case DM_X12: x12_count = 0; break; + case DM_EDIFACT: edf_count = 0; break; case DM_BASE256: b256_count = mode_arg == 249 ? DM_MULT_1 : 0; /* Adjusted to use no. of bytes written */ break; @@ -656,19 +652,24 @@ static int dm_switch_mode(const int next_mode, unsigned char target[], int tp, i case DM_ASCII: if (debug_print) fputs("ASC ", stdout); break; - case DM_C40: target[tp++] = 230; + case DM_C40: + target[tp++] = 230; if (debug_print) fputs("C40 ", stdout); break; - case DM_TEXT: target[tp++] = 239; + case DM_TEXT: + target[tp++] = 239; if (debug_print) fputs("TEX ", stdout); break; - case DM_X12: target[tp++] = 238; + case DM_X12: + target[tp++] = 238; if (debug_print) fputs("X12 ", stdout); break; - case DM_EDIFACT: target[tp++] = 240; + case DM_EDIFACT: + target[tp++] = 240; if (debug_print) fputs("EDI ", stdout); break; - case DM_BASE256: target[tp++] = 231; + case DM_BASE256: + target[tp++] = 231; *p_b256_start = tp; target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */ if (debug_print) fputs("BAS ", stdout); diff --git a/backend/dotcode.c b/backend/dotcode.c index 3359cf9f..8689705d 100644 --- a/backend/dotcode.c +++ b/backend/dotcode.c @@ -1219,7 +1219,7 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i int jc, n_dots; int data_length, ecc_length; int min_dots, min_area; - int height, width; + int height, width = 0; int mask_score[8]; int user_mask; int dot_stream_length; @@ -1243,6 +1243,14 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i symbol->eci); } + if (symbol->option_2 > 0) { + if (symbol->option_2 < 5 || symbol->option_2 > 200) { + return ZEXT errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 527, + "Number of columns '%d' is out of range (5 to 200)", symbol->option_2); + } + width = symbol->option_2; + } + user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is mask + 1, so >= 1 and <= 8 */ if (user_mask > 8) { user_mask = 0; /* Ignore */ @@ -1293,7 +1301,7 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2; min_area = min_dots * 2; - if (symbol->option_2 == 0) { + if (width == 0) { /* Automatic sizing */ /* Following Rule 3 (Section 5.2.2) and applying a recommended width to height ratio 3:2 */ /* Eliminates undersized symbols */ @@ -1334,8 +1342,9 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i } else { /* User defined width */ - width = symbol->option_2; - height = (min_area + (width - 1)) / width; + if ((height = (min_area + (width - 1)) / width) < 5) { + height = 5; + } if (!((width + height) & 1)) { height++; @@ -1359,9 +1368,9 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i if ((height < 5) || (width < 5)) { assert(height >= 5 || width >= 5); /* If width < 5, min height is 19 */ - ZEXT errtxtf(0, symbol, 529, "Resulting symbol %1$s '%2$d' is too small (minimum 5)", - width < 5 ? "width" : "height", width < 5 ? width : height); - return ZINT_ERROR_INVALID_OPTION; + return ZEXT errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 529, + "Resulting symbol %1$s '%2$d' is too small (minimum 5)", + width < 5 ? "width" : "height", width < 5 ? width : height); } n_dots = (height * width) / 2; diff --git a/backend/gridmtx.c b/backend/gridmtx.c index bc0cac32..41185327 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -363,88 +363,67 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons switch (current_mode) { case 0: switch (next_mode) { - case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp); - break; - case GM_NUMBER: bp = bin_append_posn(2, 4, binary, bp); - break; - case GM_LOWER: bp = bin_append_posn(3, 4, binary, bp); - break; - case GM_UPPER: bp = bin_append_posn(4, 4, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(5, 4, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(6, 4, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp); break; + case GM_NUMBER: bp = bin_append_posn(2, 4, binary, bp); break; + case GM_LOWER: bp = bin_append_posn(3, 4, binary, bp); break; + case GM_UPPER: bp = bin_append_posn(4, 4, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(5, 4, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(6, 4, binary, bp); break; } break; case GM_CHINESE: switch (next_mode) { - case GM_NUMBER: bp = bin_append_posn(8161, 13, binary, bp); - break; - case GM_LOWER: bp = bin_append_posn(8162, 13, binary, bp); - break; - case GM_UPPER: bp = bin_append_posn(8163, 13, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(8164, 13, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(8165, 13, binary, bp); - break; + case GM_NUMBER: bp = bin_append_posn(8161, 13, binary, bp); break; + case GM_LOWER: bp = bin_append_posn(8162, 13, binary, bp); break; + case GM_UPPER: bp = bin_append_posn(8163, 13, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(8164, 13, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(8165, 13, binary, bp); break; } break; case GM_NUMBER: /* add numeric block padding value */ switch (p) { - case 1: binary[number_pad_posn] = '1'; + case 1: + binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; /* 2 pad digits */ - case 2: binary[number_pad_posn] = '0'; + case 2: + binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; /* 1 pad digits */ - case 3: binary[number_pad_posn] = '0'; + case 3: + binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; /* 0 pad digits */ } switch (next_mode) { - case GM_CHINESE: bp = bin_append_posn(1019, 10, binary, bp); - break; - case GM_LOWER: bp = bin_append_posn(1020, 10, binary, bp); - break; - case GM_UPPER: bp = bin_append_posn(1021, 10, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(1022, 10, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(1023, 10, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(1019, 10, binary, bp); break; + case GM_LOWER: bp = bin_append_posn(1020, 10, binary, bp); break; + case GM_UPPER: bp = bin_append_posn(1021, 10, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(1022, 10, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(1023, 10, binary, bp); break; } break; case GM_LOWER: case GM_UPPER: switch (next_mode) { - case GM_CHINESE: bp = bin_append_posn(28, 5, binary, bp); - break; - case GM_NUMBER: bp = bin_append_posn(29, 5, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(28, 5, binary, bp); break; + case GM_NUMBER: bp = bin_append_posn(29, 5, binary, bp); break; case GM_LOWER: - case GM_UPPER: bp = bin_append_posn(30, 5, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(124, 7, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(126, 7, binary, bp); + case GM_UPPER: + bp = bin_append_posn(30, 5, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(124, 7, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(126, 7, binary, bp); break; } break; case GM_MIXED: switch (next_mode) { - case GM_CHINESE: bp = bin_append_posn(1009, 10, binary, bp); - break; - case GM_NUMBER: bp = bin_append_posn(1010, 10, binary, bp); - break; - case GM_LOWER: bp = bin_append_posn(1011, 10, binary, bp); - break; - case GM_UPPER: bp = bin_append_posn(1012, 10, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(1015, 10, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(1009, 10, binary, bp); break; + case GM_NUMBER: bp = bin_append_posn(1010, 10, binary, bp); break; + case GM_LOWER: bp = bin_append_posn(1011, 10, binary, bp); break; + case GM_UPPER: bp = bin_append_posn(1012, 10, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(1015, 10, binary, bp); break; } break; case GM_BYTE: @@ -452,33 +431,22 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons gm_add_byte_count(binary, byte_count_posn, byte_count); byte_count = 0; switch (next_mode) { - case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp); - break; - case GM_NUMBER: bp = bin_append_posn(2, 4, binary, bp); - break; - case GM_LOWER: bp = bin_append_posn(3, 4, binary, bp); - break; - case GM_UPPER: bp = bin_append_posn(4, 4, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(5, 4, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp); break; + case GM_NUMBER: bp = bin_append_posn(2, 4, binary, bp); break; + case GM_LOWER: bp = bin_append_posn(3, 4, binary, bp); break; + case GM_UPPER: bp = bin_append_posn(4, 4, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(5, 4, binary, bp); break; } break; } if (debug_print) { switch (next_mode) { - case GM_CHINESE: fputs("CHIN ", stdout); - break; - case GM_NUMBER: fputs("NUMB ", stdout); - break; - case GM_LOWER: fputs("LOWR ", stdout); - break; - case GM_UPPER: fputs("UPPR ", stdout); - break; - case GM_MIXED: fputs("MIXD ", stdout); - break; - case GM_BYTE: fputs("BYTE ", stdout); - break; + case GM_CHINESE: fputs("CHIN ", stdout); break; + case GM_NUMBER: fputs("NUMB ", stdout); break; + case GM_LOWER: fputs("LOWR ", stdout); break; + case GM_UPPER: fputs("UPPR ", stdout); break; + case GM_MIXED: fputs("MIXD ", stdout); break; + case GM_BYTE: fputs("BYTE ", stdout); break; } } } @@ -575,18 +543,12 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons if (ppos != -1) { switch (punt) { - case ' ': glyph = 0; - break; - case '+': glyph = 3; - break; - case '-': glyph = 6; - break; - case '.': glyph = 9; - break; - case ',': glyph = 12; - break; - case 13: glyph = 15; - break; + case ' ': glyph = 0; break; + case '+': glyph = 3; break; + case '-': glyph = 6; break; + case '.': glyph = 9; break; + case ',': glyph = 12; break; + case 13: glyph = 15; break; } glyph += ppos; glyph += 1000; @@ -726,13 +688,16 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons if (current_mode == GM_NUMBER) { /* add numeric block padding value */ switch (p) { - case 1: binary[number_pad_posn] = '1'; + case 1: + binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; /* 2 pad digits */ - case 2: binary[number_pad_posn] = '0'; + case 2: + binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; /* 1 pad digit */ - case 3: binary[number_pad_posn] = '0'; + case 3: + binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; /* 0 pad digits */ } @@ -745,17 +710,14 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons /* Add "end of data" character */ switch (current_mode) { - case GM_CHINESE: bp = bin_append_posn(8160, 13, binary, bp); - break; - case GM_NUMBER: bp = bin_append_posn(1018, 10, binary, bp); - break; + case GM_CHINESE: bp = bin_append_posn(8160, 13, binary, bp); break; + case GM_NUMBER: bp = bin_append_posn(1018, 10, binary, bp); break; case GM_LOWER: - case GM_UPPER: bp = bin_append_posn(27, 5, binary, bp); - break; - case GM_MIXED: bp = bin_append_posn(1008, 10, binary, bp); - break; - case GM_BYTE: bp = bin_append_posn(0, 4, binary, bp); + case GM_UPPER: + bp = bin_append_posn(27, 5, binary, bp); break; + case GM_MIXED: bp = bin_append_posn(1008, 10, binary, bp); break; + case GM_BYTE: bp = bin_append_posn(0, 4, binary, bp); break; } if (bp > 9191) { @@ -1187,14 +1149,10 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons data_max = 1313; switch (ecc_level) { - case 2: data_max = 1167; - break; - case 3: data_max = 1021; - break; - case 4: data_max = 875; - break; - case 5: data_max = 729; - break; + case 2: data_max = 1167; break; + case 3: data_max = 1021; break; + case 4: data_max = 875; break; + case 5: data_max = 729; break; } if (data_cw > data_max) { diff --git a/backend/library.c b/backend/library.c index c99c94d1..bd0bbec2 100644 --- a/backend/library.c +++ b/backend/library.c @@ -324,7 +324,7 @@ static int dump_plot(struct zint_symbol *symbol) { byt += 1; } } - if (((i + 1) % 4) == 0) { + if ((i + 1) % 4 == 0) { fputc(hex[byt], f); space++; byt = 0; @@ -335,7 +335,7 @@ static int dump_plot(struct zint_symbol *symbol) { } } - if ((symbol->width % 4) != 0) { + if (symbol->width % 4 != 0) { byt = byt << (4 - (symbol->width % 4)); fputc(hex[byt], f); } @@ -740,7 +740,7 @@ static int esc_base(struct zint_symbol *symbol, const unsigned char *input_strin val = (c1 << 6) | (c2 << 3) | c3; } } else { - if ((c1 >= 0) && (c2 >= 0)) { + if (c1 >= 0 && c2 >= 0) { val = (c1 << 4) | c2; } } @@ -1138,29 +1138,29 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ } /* Check other symbol fields */ - if ((symbol->scale < 0.01f) || (symbol->scale > 200.0f)) { + if (symbol->scale < 0.01f || symbol->scale > 200.0f) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 227, "Scale out of range (0.01 to 200)"); } - if ((symbol->dot_size < 0.01f) || (symbol->dot_size > 20.0f)) { + if (symbol->dot_size < 0.01f || symbol->dot_size > 20.0f) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 221, "Dot size out of range (0.01 to 20)"); } - if ((symbol->height < 0.0f) || (symbol->height > 2000.0f)) { /* Allow for 44 row CODABLOCKF at 45X each */ + if (symbol->height < 0.0f || symbol->height > 2000.0f) { /* Allow for 44 row CODABLOCKF at 45X each */ return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 765, "Height out of range (0 to 2000)"); } - if ((symbol->guard_descent < 0.0f) || (symbol->guard_descent > 50.0f)) { + if (symbol->guard_descent < 0.0f || symbol->guard_descent > 50.0f) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 769, "Guard bar descent out of range (0 to 50)"); } - if ((symbol->text_gap < -5.0f) || (symbol->text_gap > 10.0f)) { + if (symbol->text_gap < -5.0f || symbol->text_gap > 10.0f) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 219, "Text gap out of range (-5 to 10)"); } - if ((symbol->whitespace_width < 0) || (symbol->whitespace_width > 100)) { + if (symbol->whitespace_width < 0 || symbol->whitespace_width > 100) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 766, "Whitespace width out of range (0 to 100)"); } - if ((symbol->whitespace_height < 0) || (symbol->whitespace_height > 100)) { + if (symbol->whitespace_height < 0 || symbol->whitespace_height > 100) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 767, "Whitespace height out of range (0 to 100)"); } - if ((symbol->border_width < 0) || (symbol->border_width > 100)) { + if (symbol->border_width < 0 || symbol->border_width > 100) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 768, "Border width out of range (0 to 100)"); } @@ -1687,8 +1687,15 @@ unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) { if ((cap_flag & ZINT_CAP_HRT) && has_hrt(symbol_id)) { result |= ZINT_CAP_HRT; } - if ((cap_flag & ZINT_CAP_STACKABLE) && is_stackable(symbol_id)) { - result |= ZINT_CAP_STACKABLE; + if ((cap_flag & ZINT_CAP_STACKABLE) && is_bindable(symbol_id)) { + switch (symbol_id) { + case BARCODE_CODE16K: /* Stacked are not stackable */ + case BARCODE_CODE49: + break; + default: + result |= ZINT_CAP_STACKABLE; + break; + } } if ((cap_flag & ZINT_CAP_EANUPC) && is_upcean(symbol_id)) { result |= ZINT_CAP_EANUPC; @@ -1824,6 +1831,9 @@ unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) { break; } } + if ((cap_flag & ZINT_CAP_BINDABLE) && is_bindable(symbol_id)) { + result |= ZINT_CAP_BINDABLE; + } return result; } diff --git a/backend/pdf417.c b/backend/pdf417.c index 7d0e69a3..9bd6ebc8 100644 --- a/backend/pdf417.c +++ b/backend/pdf417.c @@ -173,45 +173,57 @@ static int pdf_textprocess_switch(const int curtable, const int newtable, unsign switch (curtable) { case T_ALPHA: switch (newtable) { - case T_LOWER: chainet[wnet++] = 27; /* LL */ + case T_LOWER: + chainet[wnet++] = 27; /* LL */ break; - case T_MIXED: chainet[wnet++] = 28; /* ML */ + case T_MIXED: + chainet[wnet++] = 28; /* ML */ break; - case T_PUNCT: chainet[wnet++] = 28; /* ML+PL */ + case T_PUNCT: + chainet[wnet++] = 28; /* ML+PL */ chainet[wnet++] = 25; break; } break; case T_LOWER: switch (newtable) { - case T_ALPHA: chainet[wnet++] = 28; /* ML+AL */ + case T_ALPHA: + chainet[wnet++] = 28; /* ML+AL */ chainet[wnet++] = 28; break; - case T_MIXED: chainet[wnet++] = 28; /* ML */ + case T_MIXED: + chainet[wnet++] = 28; /* ML */ break; - case T_PUNCT: chainet[wnet++] = 28; /* ML+PL */ + case T_PUNCT: + chainet[wnet++] = 28; /* ML+PL */ chainet[wnet++] = 25; break; } break; case T_MIXED: switch (newtable) { - case T_ALPHA: chainet[wnet++] = 28; /* AL */ + case T_ALPHA: + chainet[wnet++] = 28; /* AL */ break; - case T_LOWER: chainet[wnet++] = 27; /* LL */ + case T_LOWER: + chainet[wnet++] = 27; /* LL */ break; - case T_PUNCT: chainet[wnet++] = 25; /* PL */ + case T_PUNCT: + chainet[wnet++] = 25; /* PL */ break; } break; case T_PUNCT: switch (newtable) { - case T_ALPHA: chainet[wnet++] = 29; /* AL */ + case T_ALPHA: + chainet[wnet++] = 29; /* AL */ break; - case T_LOWER: chainet[wnet++] = 29; /* AL+LL */ + case T_LOWER: + chainet[wnet++] = 29; /* AL+LL */ chainet[wnet++] = 27; break; - case T_MIXED: chainet[wnet++] = 29; /* AL+ML */ + case T_MIXED: + chainet[wnet++] = 29; /* AL+ML */ chainet[wnet++] = 28; break; } @@ -1345,24 +1357,15 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int /* 796 - we now take care of the Reed Solomon codes */ switch (ecc) { - case 1: offset = 2; - break; - case 2: offset = 6; - break; - case 3: offset = 14; - break; - case 4: offset = 30; - break; - case 5: offset = 62; - break; - case 6: offset = 126; - break; - case 7: offset = 254; - break; - case 8: offset = 510; - break; - default: offset = 0; - break; + case 1: offset = 2; break; + case 2: offset = 6; break; + case 3: offset = 14; break; + case 4: offset = 30; break; + case 5: offset = 62; break; + case 6: offset = 126; break; + case 7: offset = 254; break; + case 8: offset = 510; break; + default: offset = 0; break; } for (i = 0; i < mclength; i++) { @@ -1744,6 +1747,7 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], con /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ if (debug_print) fputs("\nInternal row representation:\n", stdout); + for (i = 0; i < symbol->rows; i++) { if (debug_print) printf("row %d: ", i); bp = 0; diff --git a/backend/plessey.c b/backend/plessey.c index f1c50ded..d3660333 100644 --- a/backend/plessey.c +++ b/backend/plessey.c @@ -99,10 +99,12 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len for (i = 0; i < 8; i++) { switch (checkptr[length * 4 + i]) { - case 0: memcpy(d, "13", 2); + case 0: + memcpy(d, "13", 2); d += 2; break; - case 1: memcpy(d, "31", 2); + case 1: + memcpy(d, "31", 2); d += 2; check_digits |= (1 << i); break; @@ -352,20 +354,13 @@ INTERNAL int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int d += 2; switch (check_option) { - case 0: d = msi_plessey_nomod(symbol, source, length, raw_text, d); - break; - case 1: d = msi_plessey_mod10(symbol, source, length, no_checktext, raw_text, d); - break; - case 2: d = msi_plessey_mod1010(symbol, source, length, no_checktext, raw_text, d); - break; - case 3: d = msi_plessey_mod11(symbol, source, length, no_checktext, 7 /*IBM wrap*/, raw_text, d); - break; - case 4: d = msi_plessey_mod1110(symbol, source, length, no_checktext, 7 /*IBM wrap*/, raw_text, d); - break; - case 5: d = msi_plessey_mod11(symbol, source, length, no_checktext, 9 /*NCR wrap*/, raw_text, d); - break; - case 6: d = msi_plessey_mod1110(symbol, source, length, no_checktext, 9 /*NCR wrap*/, raw_text, d); - break; + case 0: d = msi_plessey_nomod(symbol, source, length, raw_text, d); break; + case 1: d = msi_plessey_mod10(symbol, source, length, no_checktext, raw_text, d); break; + case 2: d = msi_plessey_mod1010(symbol, source, length, no_checktext, raw_text, d); break; + case 3: d = msi_plessey_mod11(symbol, source, length, no_checktext, 7 /*IBM wrap*/, raw_text, d); break; + case 4: d = msi_plessey_mod1110(symbol, source, length, no_checktext, 7 /*IBM wrap*/, raw_text, d); break; + case 5: d = msi_plessey_mod11(symbol, source, length, no_checktext, 9 /*NCR wrap*/, raw_text, d); break; + case 6: d = msi_plessey_mod1110(symbol, source, length, no_checktext, 9 /*NCR wrap*/, raw_text, d); break; } if (!d) { diff --git a/backend/qr.c b/backend/qr.c index a16719d3..a2f0bda2 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -1293,12 +1293,9 @@ static void qr_add_format_info(unsigned char *grid, const int size, const int ec int i; switch (ecc_level) { - case QR_LEVEL_L: format |= 0x08; - break; - case QR_LEVEL_Q: format |= 0x18; - break; - case QR_LEVEL_H: format |= 0x10; - break; + case QR_LEVEL_L: format |= 0x08; break; + case QR_LEVEL_Q: format |= 0x18; break; + case QR_LEVEL_H: format |= 0x10; break; } seq = qr_annex_c[format]; @@ -2067,14 +2064,10 @@ static int microqr_evaluate(const unsigned char *grid, const int size, const int int sum1, sum2, i, filter = 0, retval; switch (pattern) { - case 0: filter = 0x01; - break; - case 1: filter = 0x02; - break; - case 2: filter = 0x04; - break; - case 3: filter = 0x08; - break; + case 0: filter = 0x01; break; + case 1: filter = 0x02; break; + case 2: filter = 0x04; break; + case 3: filter = 0x08; break; } sum1 = 0; @@ -2418,8 +2411,6 @@ INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int lengt char *mode = (char *) z_alloca(length + 1); unsigned char *preprocessed = (unsigned char *) z_alloca(length + 1); - symbol->eci = 4; /* Set before any processing */ - user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is pattern + 1, so >= 1 and <= 8 */ if (user_mask > 8) { user_mask = 0; /* Ignore */ diff --git a/backend/raster.c b/backend/raster.c index b272acc5..851d56cc 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -1341,7 +1341,7 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl } /* Separator binding for stacked barcodes */ - if ((symbol->output_options & BARCODE_BIND) && (symbol->rows > 1) && is_stackable(symbol->symbology)) { + if ((symbol->output_options & BARCODE_BIND) && symbol->rows > 1 && is_bindable(symbol->symbology)) { int sep_xoffset_si = xoffset_si; int sep_width_si = symbol->width * si; int sep_height_si, sep_yoffset_si; diff --git a/backend/rss.c b/backend/rss.c index cc23a19c..b6ad9a72 100644 --- a/backend/rss.c +++ b/backend/rss.c @@ -127,7 +127,7 @@ static void getRSSwidths(int widths[], int val, int n, const int elements, const /* Get all combinations */ subVal = rss_combins(n - elmWidth - 1, elements - bar - 2); /* Less combinations with no single-module element */ - if ((!noNarrow) && (!narrowMask) + if (!noNarrow && !narrowMask && (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) { subVal -= rss_combins(n - elmWidth - (elements - bar), elements - bar - 2); } @@ -295,12 +295,10 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int int data_character[4] = {0}, data_group[4] = {0}, v_odd[4], v_even[4]; int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer; int latch; - int separator_row; + int separator_row = 0; int widths[4]; const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; - separator_row = 0; - if (length > 14) { /* Allow check digit to be specified (will be verified and ignored) */ return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 380, "Input length %d too long (maximum 14)", length); } @@ -317,14 +315,17 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int length--; /* Ignore */ } + if (symbol->symbology != BARCODE_DBAR_OMN) { + symbol->rows = 0; /* Stacked (and composites) are not stackable */ + } + /* Make some room for a separator row for composite symbols */ switch (symbol->symbology) { case BARCODE_DBAR_OMN_CC: case BARCODE_DBAR_STK_CC: case BARCODE_DBAR_OMNSTK_CC: - separator_row = symbol->rows; + separator_row = symbol->rows++; symbol->row_height[separator_row] = 1; - symbol->rows += 1; break; } @@ -405,7 +406,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int /* Use DataBar subset width algorithm */ for (i = 0; i < 4; i++) { - if ((i == 0) || (i == 2)) { + if (i == 0 || i == 2) { getRSSwidths(widths, v_odd[i], dbar_modules_odd[data_group[i]], 4, dbar_widest_odd[data_group[i]], 1); data_widths[0][i] = widths[0]; data_widths[2][i] = widths[1]; @@ -471,7 +472,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int } /* Put this data into the symbol */ - if ((symbol->symbology == BARCODE_DBAR_OMN) || (symbol->symbology == BARCODE_DBAR_OMN_CC)) { + if (symbol->symbology == BARCODE_DBAR_OMN || symbol->symbology == BARCODE_DBAR_OMN_CC) { writer = 0; latch = 0; for (i = 0; i < 46; i++) { @@ -484,7 +485,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int /* Separator pattern for composite symbol */ dbar_omn_separator(symbol, 96, separator_row, 1 /*above*/, 18, 63, 0 /*bottom_finder_value_3*/); } - symbol->rows = symbol->rows + 1; + symbol->rows++; /* Set human readable text */ dbar_set_gtin14_hrt(symbol, source, length); @@ -505,7 +506,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int } } - } else if ((symbol->symbology == BARCODE_DBAR_STK) || (symbol->symbology == BARCODE_DBAR_STK_CC)) { + } else if (symbol->symbology == BARCODE_DBAR_STK || symbol->symbology == BARCODE_DBAR_STK_CC) { /* Top row */ writer = 0; latch = 0; @@ -517,7 +518,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int symbol->row_height[symbol->rows] = 5.0f; /* ISO/IEC 24724:2011 5.3.2.1 set to 5X */ /* Bottom row */ - symbol->rows = symbol->rows + 2; + symbol->rows += 2; set_module(symbol, symbol->rows, 0); unset_module(symbol, symbol->rows, 1); writer = 2; @@ -549,7 +550,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int /* Separator pattern for composite symbol */ dbar_omn_separator(symbol, 50, separator_row, 1 /*above*/, 18, 0, 0 /*bottom_finder_value_3*/); } - symbol->rows = symbol->rows + 1; + symbol->rows++; if (symbol->width < 50) { symbol->width = 50; } @@ -558,7 +559,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int error_number = dbar_omnstk_set_height(symbol, 0 /*first_row*/); } - } else if ((symbol->symbology == BARCODE_DBAR_OMNSTK) || (symbol->symbology == BARCODE_DBAR_OMNSTK_CC)) { + } else if (symbol->symbology == BARCODE_DBAR_OMNSTK || symbol->symbology == BARCODE_DBAR_OMNSTK_CC) { /* Top row */ writer = 0; latch = 0; @@ -569,7 +570,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int unset_module(symbol, symbol->rows, writer + 1); /* Bottom row */ - symbol->rows = symbol->rows + 4; + symbol->rows += 4; set_module(symbol, symbol->rows, 0); unset_module(symbol, symbol->rows, 1); writer = 2; @@ -600,7 +601,7 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int /* Separator pattern for composite symbol */ dbar_omn_separator(symbol, 50, separator_row, 1 /*above*/, 18, 0, 0 /*bottom_finder_value_3*/); } - symbol->rows = symbol->rows + 1; + symbol->rows++; /* ISO/IEC 24724:2011 5.3.2.2 minimum 33X height per row */ if (symbol->symbology == BARCODE_DBAR_OMNSTK_CC) { @@ -638,12 +639,10 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int int left_widths[14], right_widths[14]; int checksum, check_elements[14], total_widths[47], writer; int latch; - int separator_row; + int separator_row = 0; int widths[7]; const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; - separator_row = 0; - if (length > 14) { /* Allow check digit to be specified (will be verified and ignored) */ return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 382, "Input length %d too long (maximum 14)", length); } @@ -661,16 +660,15 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int } if (length == 13) { - if ((source[0] != '0') && (source[0] != '1')) { + if (source[0] != '0' && source[0] != '1') { return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 384, "Input value out of range (0 to 1999999999999)"); } } /* Make some room for a separator row for composite symbols */ if (symbol->symbology == BARCODE_DBAR_LTD_CC) { - separator_row = symbol->rows; + separator_row = symbol->rows++; symbol->row_height[separator_row] = 1; - symbol->rows += 1; } large_load_str_u64(&accum, source, length); @@ -785,7 +783,7 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int if (symbol->width < writer) { symbol->width = writer; } - symbol->rows = symbol->rows + 1; + symbol->rows++; /* Add separator pattern if composite symbol */ if (symbol->symbology == BARCODE_DBAR_LTD_CC) { @@ -865,7 +863,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha /* Decide whether a compressed data field is required and if so what method to use - method 2 = no compressed data field */ - if ((length >= 16) && ((source[0] == '0') && (source[1] == '1'))) { + if (length >= 16 && source[0] == '0' && source[1] == '1') { /* (01) and other AIs */ encoding_method = 1; if (debug_print) fputs("Choosing Method 1\n", stdout); @@ -875,12 +873,12 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha if (debug_print) fputs("Choosing Method 2\n", stdout); } - if (((length >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { + if (length >= 20 && encoding_method == 1 && source[2] == '9' && source[16] == '3') { /* Possibly encoding method > 2 */ if (debug_print) fputs("Checking for other methods\n", stdout); - if ((length >= 26) && (source[17] == '1') && (source[18] == '0')) { + if (length >= 26 && source[17] == '1' && source[18] == '0') { /* Methods 3, 7, 9, 11 and 13 */ /* (01) and (310x) */ @@ -890,7 +888,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha if (weight >= 0 && weight <= 99999) { if (length == 26) { - if ((source[19] == '3') && weight <= 32767) { /* In grams, max 32.767 kilos */ + if (source[19] == '3' && weight <= 32767) { /* In grams, max 32.767 kilos */ /* (01) and (3103) */ encoding_method = 3; } else { @@ -898,7 +896,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha encoding_method = 7; } - } else if ((length == 34) && (source[26] == '1') + } else if (length == 34 && source[26] == '1' && (source[27] == '1' || source[27] == '3' || source[27] == '5' || source[27] == '7') && dbar_date(source, length, 28) >= 0) { @@ -910,7 +908,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha } } - } else if ((length >= 26) && (source[17] == '2') && (source[18] == '0')) { + } else if (length >= 26 && source[17] == '2' && source[18] == '0') { /* Methods 4, 8, 10, 12 and 14 */ /* (01) and (320x) */ @@ -929,7 +927,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha encoding_method = 8; } - } else if ((length == 34) && (source[26] == '1') + } else if (length == 34 && source[26] == '1' && (source[27] == '1' || source[27] == '3' || source[27] == '5' || source[27] == '7') && dbar_date(source, length, 28) >= 0) { @@ -941,7 +939,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha } } - } else if ((source[17] == '9') && ((source[19] >= '0') && (source[19] <= '3'))) { + } else if (source[17] == '9' && (source[19] >= '0' && source[19] <= '3')) { /* Methods 5 and 6 */ if (source[18] == '2') { /* (01) and (392x) */ @@ -956,10 +954,12 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha } switch (encoding_method) { /* Encoding method - Table 10 */ - case 1: bp = bin_append_posn(4, 3, binary_string, bp); /* "1XX" */ + case 1: + bp = bin_append_posn(4, 3, binary_string, bp); /* "1XX" */ read_posn = 16; break; - case 2: bp = bin_append_posn(0, 4, binary_string, bp); /* "00XX" */ + case 2: + bp = bin_append_posn(0, 4, binary_string, bp); /* "00XX" */ read_posn = 0; break; case 3: /* 0100 */ @@ -967,10 +967,12 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha bp = bin_append_posn(4 + (encoding_method - 3), 4, binary_string, bp); read_posn = 26; break; - case 5: bp = bin_append_posn(0x30, 7, binary_string, bp); /* "01100XX" */ + case 5: + bp = bin_append_posn(0x30, 7, binary_string, bp); /* "01100XX" */ read_posn = 20; break; - case 6: bp = bin_append_posn(0x34, 7, binary_string, bp); /* "01101XX" */ + case 6: + bp = bin_append_posn(0x34, 7, binary_string, bp); /* "01101XX" */ read_posn = 23; break; default: /* Modes 7 to 14 */ @@ -1008,7 +1010,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - } else if ((encoding_method == 3) || (encoding_method == 4)) { + } else if (encoding_method == 3 || encoding_method == 4) { /* Encoding method field "0100" - variable weight item (0,001 kilogram increments) */ /* Encoding method field "0101" - variable weight item (0,01 or 0,001 pound increment) */ @@ -1016,13 +1018,13 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - if ((encoding_method == 4) && (source[19] == '3')) { + if (encoding_method == 4 && source[19] == '3') { bp = bin_append_posn(to_int(source + 20, 6) + 10000, 15, binary_string, bp); } else { bp = bin_append_posn(to_int(source + 20, 6), 15, binary_string, bp); } - } else if ((encoding_method == 5) || (encoding_method == 6)) { + } else if (encoding_method == 5 || encoding_method == 6) { /* Encoding method "01100" - variable measure item and price */ /* Encoding method "01101" - variable measure item and price with ISO 4217 Currency Code */ @@ -1036,7 +1038,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha bp = bin_append_posn(to_int(source + 20, 3), 10, binary_string, bp); /* 3-digit currency */ } - } else if ((encoding_method >= 7) && (encoding_method <= 14)) { + } else if (encoding_method >= 7 && encoding_method <= 14) { /* Encoding method fields "0111000" through "0111111" - variable weight item plus date */ int group_val; unsigned char weight_str[7]; @@ -1117,7 +1119,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha /* There is still one more numeric digit to encode */ if (debug_print) fputs("Adding extra (odd) numeric digit\n", stdout); - if ((remainder >= 4) && (remainder <= 6)) { + if (remainder >= 4 && remainder <= 6) { bp = bin_append_posn(ctoi(last_digit) + 1, 4, binary_string, bp); } else { d1 = ctoi(last_digit); @@ -1186,7 +1188,7 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha } else if (encoding_method == 2) { binary_string[3] = d1 ? '1' : '0'; binary_string[4] = d2 ? '1' : '0'; - } else if ((encoding_method == 5) || (encoding_method == 6)) { + } else if (encoding_method == 5 || encoding_method == 6) { binary_string[6] = d1 ? '1' : '0'; binary_string[7] = d2 ? '1' : '0'; } @@ -1285,7 +1287,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int int latch; int char_widths[21][8], checksum, check_widths[8], c_group; int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer; - int separator_row; + int separator_row = 0; /* Allow for 8 bits + 5-bit latch per char + 200 bits overhead/padding */ unsigned int bin_len = 13 * length + 200 + 1; int widths[4]; @@ -1299,8 +1301,6 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int char *binary_string = (char *) z_alloca(bin_len); const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; - separator_row = 0; - error_number = gs1_verify(symbol, source, length, reduced, &reduced_length); if (error_number >= ZINT_ERROR) { return error_number; @@ -1311,11 +1311,14 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int printf("Reduced (%d): %s\n", reduced_length, reduced); } - if ((symbol->symbology == BARCODE_DBAR_EXP_CC) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { + if (symbol->symbology != BARCODE_DBAR_EXP) { + symbol->rows = 0; /* Stacked (and composites) are not stackable */ + } + + if (symbol->symbology == BARCODE_DBAR_EXP_CC || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { /* Make space for a composite separator pattern */ - separator_row = symbol->rows; + separator_row = symbol->rows++; symbol->row_height[separator_row] = 1; - symbol->rows += 1; } if (cc_rows) { /* The "component linkage" flag */ @@ -1324,7 +1327,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int binary_string[bp++] = '0'; } - if ((symbol->symbology == BARCODE_DBAR_EXPSTK) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { + if (symbol->symbology == BARCODE_DBAR_EXPSTK || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { cols_per_row = 2; /* Default */ if (symbol->option_2 >= 1 && symbol->option_2 <= 11) { cols_per_row = symbol->option_2; @@ -1345,7 +1348,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int return error_number; } - if ((symbol->symbology == BARCODE_DBAR_EXPSTK) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { + if (symbol->symbology == BARCODE_DBAR_EXPSTK || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { /* Feedback options */ symbol->option_2 = cols_per_row; symbol->option_3 = max_rows; @@ -1470,7 +1473,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int } } - if ((symbol->symbology == BARCODE_DBAR_EXP) || (symbol->symbology == BARCODE_DBAR_EXP_CC)) { + if (symbol->symbology == BARCODE_DBAR_EXP || symbol->symbology == BARCODE_DBAR_EXP_CC) { /* Copy elements into symbol */ elements[0] = 1; /* Left guard */ @@ -1487,7 +1490,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int if (symbol->width < writer) { symbol->width = writer; } - symbol->rows = symbol->rows + 1; + symbol->rows++; dbar_exp_hrt(symbol, source, length); @@ -1496,9 +1499,9 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int } } else { + /* BARCODE_DBAR_EXPSTK || BARCODE_DBAR_EXPSTK_CC */ int current_row, current_block, left_to_right; int v2_latch = 0; - /* RSS Expanded Stacked */ /* Bug corrected: Character missing for message * [01]90614141999996[10]1234222222222221 @@ -1531,7 +1534,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int /* If last row and is partial and even-numbered, and have even columns (segment pairs), and odd number of finders (== odd number of columns) */ - if ((current_row == stack_rows) && (num_columns != cols_per_row) && !(current_row & 1) + if (current_row == stack_rows && num_columns != cols_per_row && !(current_row & 1) && !(cols_per_row & 1) && (num_columns & 1)) { /* Special case bottom row */ special_case_row = 1; @@ -1558,7 +1561,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int do { i = 2 + (current_block * 21); for (j = 0; j < 21; j++) { - if ((i + j) < pattern_width) { + if (i + j < pattern_width) { if (left_to_right) { sub_elements[j + (reader * 21) + 2] = elements[i + j]; } else { @@ -1608,9 +1611,9 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int symbol->row_height[symbol->rows + 1] = 1; } - symbol->rows = symbol->rows + 4; + symbol->rows += 4; } - symbol->rows = symbol->rows - 3; + symbol->rows -= 3; if (raw_text && rt_cpy(symbol, reduced, reduced_length)) { return ZINT_ERROR_MEMORY; /* `rt_cpy()` only fails with OOM */ diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt index 8a3f5009..ffe17cda 100644 --- a/backend/tests/CMakeLists.txt +++ b/backend/tests/CMakeLists.txt @@ -81,6 +81,7 @@ zint_add_test(medical test_medical) zint_add_test(output test_output) zint_add_test(pcx test_pcx) zint_add_test(pdf417 test_pdf417) +zint_add_test(perf test_perf) zint_add_test(plessey test_plessey) if(ZINT_USE_PNG AND PNG_FOUND) zint_add_test(png test_png) @@ -89,6 +90,7 @@ zint_add_test(postal test_postal) zint_add_test(print test_print) zint_add_test(ps test_ps) zint_add_test(qr test_qr) +zint_add_test(random test_random) zint_add_test(raster test_raster) zint_add_test(reedsol test_reedsol) zint_add_test(rss test_rss) diff --git a/backend/tests/README b/backend/tests/README index 248988dc..b0eff2f9 100644 --- a/backend/tests/README +++ b/backend/tests/README @@ -1,4 +1,4 @@ -% backend/tests/README 2024-11-18 +% backend/tests/README 2025-04-03 Zint backend test suite ----------------------- @@ -125,6 +125,18 @@ To run a test against ZXing-C++ (if any), use '-d 512': backend/tests/test_rss -d 512 + ------------------------------------------------------------------------ + For testing against ZXing-C++, the "diagnostics2" branch from + https://github.com/gitlost/zxing-cpp is required, built with + ZXING_EXAMPLE_DECODER defined, and "zxingcppdecoder" placed in PATH, + e.g.: + git clone --branch diagnostics2 https://github.com/gitlost/zxing-cpp \ + zxing-cpp-diagnostics2 + cd zxing-cpp-diagnostics2 && mkdir build && cd build + cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DZXING_EXAMPLE_DECODER=ON .. + make && sudo make install + ------------------------------------------------------------------------ + (see also /backend/tests/tools/run_zxingcpp_tests.sh) To generate test data (if available), use '-g': diff --git a/backend/tests/test_2of5.c b/backend/tests/test_2of5.c index ab4bc07c..0bac2404 100644 --- a/backend/tests/test_2of5.c +++ b/backend/tests/test_2of5.c @@ -459,108 +459,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_C25INTER, -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 1, 819, "C25INTER 90" }, - /* 1*/ { BARCODE_C25INTER, -1, "1234567890", 0, 1, 99, "C25INTER 10" }, - /* 2*/ { BARCODE_C25STANDARD, -1, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 1, 817, "C25STANDARD 80" }, - /* 3*/ { BARCODE_C25STANDARD, -1, "1234567890", 0, 1, 117, "C25STANDARD 10" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -568,7 +466,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_aztec.c b/backend/tests/test_aztec.c index 2b2c33c8..a789d2bb 100644 --- a/backend/tests/test_aztec.c +++ b/backend/tests/test_aztec.c @@ -4161,122 +4161,6 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITERATIONS 1000 - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_AZTEC, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" - "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - 0, 49, 49, "286 chars, 8-bit words, upper" }, - /* 1*/ { BARCODE_AZTEC, -1, -1, -1, - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", - 0, 79, 79, "900 chars, 10-bit words, numeric" }, - /* 2*/ { BARCODE_AZTEC, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377", - 0, 91, 91, "980 chars, 10-bit words, mixed" }, - /* 3*/ { BARCODE_AZTEC, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377", - 0, 113, 113, "1540 chars, 12-bit words, mixed" }, - /* 4*/ { BARCODE_AZRUNE, -1, -1, -1, - "255", - 0, 11, 11, "3 chars, AZRUNE" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, - data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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 (p_ctx->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 */ @@ -4287,7 +4171,6 @@ int main(int argc, char *argv[]) { { "test_rt", test_rt }, { "test_rt_segs", test_rt_segs }, { "test_fuzz", test_fuzz }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_bwipp.c b/backend/tests/test_bwipp.c index 936c7ee0..73e4da0a 100644 --- a/backend/tests/test_bwipp.c +++ b/backend/tests/test_bwipp.c @@ -1,3 +1,4 @@ +/* Test BWIPP against ZXing-C++ (no zint involved) */ /* libzint - the open source barcode library Copyright (C) 2025 Robin Stuart @@ -29,45 +30,29 @@ */ /* SPDX-License-Identifier: BSD-3-Clause */ +#include #include "testcommon.h" -static int aztec_width(const int bwipp_len) { - static const int width_lens[33] = { - 15 * 15, 19 * 19, 23 * 23, 27 * 27, 31 * 31, 37 * 37, 41 * 41, 45 * 45, 49 * 49, 53 * 53, - 57 * 57, 61 * 61, 67 * 67, 71 * 71, 75 * 75, 79 * 79, 83 * 83, 87 * 87, 91 * 91, 95 * 95, - 101 * 101, 105 * 105, 109 * 109, 113 * 113, 117 * 117, 121 * 121, 125 * 125, 131 * 131, 135 * 135, 139 * 139, - 143 * 143, 147 * 147, 151 * 151, - }; - static const int widths[33] = { - 15, 19, 23, 27, 31, 37, 41, 45, 49, 53, - 57, 61, 67, 71, 75, 79, 83, 87, 91, 95, - 101, 105, 109, 113, 117, 121, 125, 131, 135, 139, - 143, 147, 151, - }; - int i; +#define FLAG_FULL_8BIT 0 +#define FLAG_LATIN_1 1 +#define FLAG_ASCII 2 - for (i = ARRAY_SIZE(width_lens) - 1; i >= 0 && width_lens[i] != bwipp_len; i--); - return i >= 0 ? widths[i] : 0; -} +struct random_item { + int data_flag; + int symbology; + int input_mode; + int eci; + int option_1; + int option_2; + int option_3; + int output_options; + int max_len; +}; -static int cnv_hex_data(const char *hex, char *buf, const int buf_size) { - const char *h = hex; - const char *const he = hex + strlen(hex); - char *str_end; - int i; +typedef int (*random_width_func_t)(const struct random_item *, const int); - for (i = 0; i < buf_size && h < he; i++) { - buf[i] = (char) strtol(h, &str_end, 16); - if (str_end == h) { - return -1; - } - h = str_end + 1; - } - if (i < buf_size) buf[i] = '\0'; - return i == buf_size ? -1 : i; -} - -static void test_aztec_random(const testCtx *const p_ctx) { +static void test_bwipp_random(const testCtx *const p_ctx, const struct random_item *rdata, + random_width_func_t width_func) { #ifndef _WIN32 int debug = p_ctx->debug; @@ -76,23 +61,15 @@ static void test_aztec_random(const testCtx *const p_ctx) { struct zint_symbol *symbol = NULL; #ifndef _WIN32 - int symbology = BARCODE_AZTEC; - int input_mode = DATA_MODE; - int eci = 899; - int option_1 = 1; - int option_2 = -1; - int option_3 = -1; - int output_options = -1; - char data_buf[4096]; - char bwipp_buf[32768]; - char escaped[8192]; - char escaped2[8192]; - char cmp_buf[8192]; - char cmp_msg[8192]; - char ret_buf[8192] = {0}; /* Suppress clang -fsanitize=memory false positive */ + char bwipp_buf[0x100000]; /* Megabyte */ + char escaped[40960]; + char escaped2[40960]; + char cmp_buf[0x100000]; + char cmp_msg[40960]; + char ret_buf[40960] = {0}; /* Suppress clang -fsanitize=memory false positive */ - const int iterations = p_ctx->arg ? p_ctx->arg : 10000; /* Use "-a N" to set iterations */ + const int iterations = p_ctx->arg ? p_ctx->arg : 10000; /* Use "-a N" to set iterations */ /* Requires to be run with "-d 1024" (see ZINT_DEBUG_TEST_BWIPP_ZXINGCPP in "testcommon.h") */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP_ZXINGCPP) && testUtilHaveGhostscript(); @@ -117,31 +94,30 @@ static void test_aztec_random(const testCtx *const p_ctx) { for (i = 0; i < iterations; i++) { int bwipp_len, cmp_len, ret_len; - length = arc4random_uniform(1800) + 1; + length = arc4random_uniform(rdata->max_len) + 1; arc4random_buf(data_buf, length); - testUtilSetSymbol(symbol, symbology, input_mode, eci, option_1, option_2, option_3, - output_options, data_buf, length, debug); + testUtilSetSymbol(symbol, rdata->symbology, rdata->input_mode, rdata->eci, + rdata->option_1, rdata->option_2, rdata->option_3, rdata->output_options, + data_buf, length, debug); - assert_nonzero(testUtilCanBwipp(i, symbol, option_1, option_2, option_3, debug), + assert_nonzero(testUtilCanBwipp(i, symbol, rdata->option_1, rdata->option_2, rdata->option_3, debug), "i:%d testUtilCanBwipp != 0\n", i); assert_nonzero(testUtilCanZXingCPP(i, symbol, data_buf, length, debug), "i:%d testUtilCanZXingCPP != 0\n", i); symbol->rows = 0; - ret = testUtilBwipp(i, symbol, option_1, option_2, option_3, data_buf, length, NULL, bwipp_buf, - sizeof(bwipp_buf), NULL); + ret = testUtilBwipp(i, symbol, rdata->option_1, rdata->option_2, rdata->option_3, data_buf, length, NULL, + bwipp_buf, sizeof(bwipp_buf), NULL); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); bwipp_len = strlen(bwipp_buf); assert_nonzero(bwipp_len, "i:%d bwipp_len %d = 0\n", i, bwipp_len); - symbol->width = aztec_width(bwipp_len); - assert_equal(symbol->width * symbol->width, bwipp_len, - "i:%d symbol->width^2 %d != bwipp_len %d (symbol->width %d)\n", - i, symbol->width * symbol->width, bwipp_len, symbol->width); + symbol->width = width_func ? width_func(rdata, bwipp_len) : bwipp_len; + assert_nonzero(symbol->width, "i:%d symbol->width zero\n", i); - ret = testUtilZXingCPP(i, symbol, data_buf, length, bwipp_buf, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), + ret = testUtilZXingCPP(i, symbol, data_buf, length, bwipp_buf, 899 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); /*fprintf(stderr, "cmp_len %d\n", cmp_len);*/ @@ -160,6 +136,162 @@ static void test_aztec_random(const testCtx *const p_ctx) { #endif /* _WIN32 */ } +static int sqrt_width_func(const struct random_item *rdata, const int bwipp_len) { + const int width = (int) sqrt(bwipp_len); + const int sq = width * width; + (void)rdata; + if (sq != bwipp_len) { + fprintf(stderr, "sqrt_width_func: width %d, bwipp_len %d, sq %d\n", width, bwipp_len, sq); + } + return sq == bwipp_len? width : 0; +} + +static void test_aztec(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_AZTEC, DATA_MODE, 899, -1, -1, -1, -1, 1600 + }; + + test_bwipp_random(p_ctx, &rdata, sqrt_width_func); +} + +static int codablockf_width_func(const struct random_item *rdata, const int bwipp_len) { + const int row_bits = rdata->option_2 * 11 + 2; + const int mod = bwipp_len % row_bits; + if (mod) { + fprintf(stderr, "codablockf_width_func: row_bits %d, bwipp_len %d, mod %d\n", row_bits, bwipp_len, mod); + } + return mod == 0 ? row_bits : 0; +} + +static void test_codablockf(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_LATIN_1, BARCODE_CODABLOCKF, DATA_MODE, 0, -1, 30 + 5, -1, -1, 500 + }; + + test_bwipp_random(p_ctx, &rdata, codablockf_width_func); +} + +static void test_code128(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_LATIN_1, BARCODE_CODE128, DATA_MODE, 0, -1, -1, -1, -1, 80 + }; + + test_bwipp_random(p_ctx, &rdata, NULL /*width_func*/); +} + +static void test_datamatrix(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_DATAMATRIX, DATA_MODE, 0, -1, 21, DM_SQUARE, -1, 800 + }; + + test_bwipp_random(p_ctx, &rdata, sqrt_width_func); +} + +/* TODO: explore why "zxingcppdecoder" fails */ +#if 0 +static int dotcode_width_func(const struct random_item *rdata, const int bwipp_len) { + const int row_bits = rdata->option_2 >= 1 ? bwipp_len / rdata->option_2 : 0; + const int mod = row_bits ? bwipp_len % row_bits : -1; + if (mod) { + fprintf(stderr, "dotcode_width_func: row_bits %d, bwipp_len %d, mod %d\n", row_bits, bwipp_len, mod); + } + return mod == 0 ? row_bits : 0; +} + +static void test_dotcode(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_DOTCODE, DATA_MODE, 0, -1, 50, -1, -1, 200 + }; + + test_bwipp_random(p_ctx, &rdata, dotcode_width_func); +} +#endif + +static int micropdf417_width_func(const struct random_item *rdata, const int bwipp_len) { + static const short widths[4] = { 38, 55, 82, 99 }; + const int row_bits = rdata->option_2 >= 1 && rdata->option_2 <= 4 ? widths[rdata->option_2 - 1] : 0; + const int mod = row_bits ? bwipp_len % row_bits : -1; + if (mod) { + fprintf(stderr, "micropdf417_width_func: row_bits %d, bwipp_len %d, mod %d\n", row_bits, bwipp_len, mod); + } + return mod == 0 ? row_bits : 0; +} + +static void test_micropdf417(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_MICROPDF417, DATA_MODE, 0, -1, 4, -1, -1, 120 + }; + + test_bwipp_random(p_ctx, &rdata, micropdf417_width_func); +} + +static int pdf417_width_func(const struct random_item *rdata, const int bwipp_len) { + const int row_bits = (rdata->option_2 + 4) * 17 + 1; + const int mod = bwipp_len % row_bits; + if (mod) { + fprintf(stderr, "pdf417_width_func: row_bits %d, bwipp_len %d, mod %d\n", row_bits, bwipp_len, mod); + } + return mod == 0 ? row_bits : 0; +} + +static void test_pdf417(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_PDF417, DATA_MODE, 0, -1, 20, -1, -1, 800 + }; + + test_bwipp_random(p_ctx, &rdata, pdf417_width_func); +} + +static void test_qr(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_QRCODE, DATA_MODE, 0, 1, 21, -1, -1, 800 + }; + + test_bwipp_random(p_ctx, &rdata, sqrt_width_func); +} + +static int rmqr_width_func(const struct random_item *rdata, const int bwipp_len) { + static const short vers[32] = { + 43, 59, 77, 99, 139, + 43, 59, 77, 99, 139, + 27, 43, 59, 77, 99, 139, + 27, 43, 59, 77, 99, 139, + 43, 59, 77, 99, 139, + 43, 59, 77, 99, 139, + }; + const int row_bits = rdata->option_2 >= 1 && rdata->option_2 <= ARRAY_SIZE(vers) ? vers[rdata->option_2 - 1] : 0; + if (row_bits == 0) { + fprintf(stderr, "rmqr_width_func: row_bits %d, bwipp_len %d, option_2 %d\n", row_bits, bwipp_len, + rdata->option_2); + } + return row_bits; +} + +static void test_rmqr(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_RMQR, DATA_MODE, 0, 2, 32, -1, -1, 140 + }; + + test_bwipp_random(p_ctx, &rdata, rmqr_width_func); +} + +static int cnv_hex_data(const char *hex, char *buf, const int buf_size) { + const char *h = hex; + const char *const he = hex + strlen(hex); + char *str_end; + int i; + + for (i = 0; i < buf_size && h < he; i++) { + buf[i] = (char) strtol(h, &str_end, 16); + if (str_end == h) { + return -1; + } + h = str_end + 1; + } + if (i < buf_size) buf[i] = '\0'; + return i == buf_size ? -1 : i; +} + static void test_aztec_bwipjs_354(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -281,7 +413,7 @@ static void test_aztec_bwipjs_354(const testCtx *const p_ctx) { bwipp_len = strlen(bwipp_buf); assert_nonzero(bwipp_len, "i:%d bwipp_len %d = 0\n", i, bwipp_len); - symbol->width = aztec_width(bwipp_len); + symbol->width = sqrt_width_func(NULL /*rdata*/, bwipp_len); assert_equal(symbol->width * symbol->width, bwipp_len, "i:%d symbol->width^2 %d != bwipp_len %d (symbol->width %d)\n", i, symbol->width * symbol->width, bwipp_len, symbol->width); @@ -304,11 +436,111 @@ static void test_aztec_bwipjs_354(const testCtx *const p_ctx) { testFinish(); } +static void test_codablockf_fnc4_digit(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + const char *data; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { "EE 9F 56 C8 B6 37 36 37" }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + struct random_item s_rdata = { 0, BARCODE_CODABLOCKF, DATA_MODE, 0, -1, 8 + 5, -1, -1, 0 }; + struct random_item *rdata = &s_rdata; + + char data_buf[4096]; + char bwipp_buf[32768]; + char escaped[8192]; + char escaped2[8192]; + char cmp_buf[8192]; + char cmp_msg[8192]; + char ret_buf[8192] = {0}; /* Suppress clang -fsanitize=memory false positive */ + + /* Requires to be run with "-d 1024" (see ZINT_DEBUG_TEST_BWIPP_ZXINGCPP in "testcommon.h") */ + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP_ZXINGCPP) && testUtilHaveGhostscript(); + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_BWIPP_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); + + testStartSymbol(p_ctx->func_name, &symbol); + + if (!do_bwipp || !do_zxingcpp) { + testSkip("Test requires BWIPP and ZXing-C++"); + return; + } + + for (i = 0; i < data_size; i++) { + int bwipp_len, cmp_len, ret_len; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + length = cnv_hex_data(data[i].data, data_buf, ARRAY_SIZE(data_buf)); + assert_nonzero(length, "i:%d cnv_hex_data length zero\n", i); + + #if 0 + debug_print_escape(TCU(data_buf), length, NULL); + printf("\n"); + #endif + + testUtilSetSymbol(symbol, rdata->symbology, rdata->input_mode, rdata->eci, + rdata->option_1, rdata->option_2, rdata->option_3, rdata->output_options, + data_buf, length, debug); + + assert_nonzero(testUtilCanBwipp(i, symbol, rdata->option_1, rdata->option_2, rdata->option_3, debug), + "i:%d testUtilCanBwipp != 0\n", i); + assert_nonzero(testUtilCanZXingCPP(i, symbol, data_buf, length, debug), "i:%d testUtilCanZXingCPP != 0\n", i); + + symbol->rows = 0; + ret = testUtilBwipp(i, symbol, rdata->option_1, rdata->option_2, rdata->option_3, data_buf, length, NULL, + bwipp_buf, sizeof(bwipp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + + bwipp_len = strlen(bwipp_buf); + assert_nonzero(bwipp_len, "i:%d bwipp_len %d = 0\n", i, bwipp_len); + + symbol->width = codablockf_width_func(rdata, bwipp_len); + assert_nonzero(symbol->width, "i:%d symbol->width == 0\n", i); + + ret = testUtilZXingCPP(i, symbol, data_buf, length, bwipp_buf, 899 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), + &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + /*fprintf(stderr, "cmp_len %d\n", cmp_len);*/ + + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data_buf, length, NULL /*primary*/, + ret_buf, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, + testUtilEscape(cmp_buf, cmp_len, escaped, sizeof(escaped)), + testUtilEscape(ret_buf, ret_len, escaped2, sizeof(escaped2))); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ - { "test_aztec_random", test_aztec_random }, + { "test_aztec", test_aztec }, + { "test_codablockf", test_codablockf }, + { "test_code128", test_code128 }, + { "test_datamatrix", test_datamatrix }, + #if 0 + { "test_dotcode", test_dotcode }, + #endif + { "test_micropdf417", test_micropdf417 }, + { "test_pdf417", test_pdf417 }, + { "test_qr", test_qr }, + { "test_rmqr", test_rmqr }, { "test_aztec_bwipjs_354", test_aztec_bwipjs_354 }, + { "test_codablockf_fnc4_digit", test_codablockf_fnc4_digit }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_codablock.c b/backend/tests/test_codablock.c index c5a0dd5a..7a445112 100644 --- a/backend/tests/test_codablock.c +++ b/backend/tests/test_codablock.c @@ -102,18 +102,26 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); @@ -183,13 +191,18 @@ static void test_options(const testCtx *const p_ctx) { data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); } assert_equal(symbol->option_1, data[i].expected_option_1, "i:%d symbol->option_1 %d != %d (option_2 %d)\n", i, symbol->option_1, data[i].expected_option_1, symbol->option_2); @@ -238,21 +251,28 @@ static void test_reader_init(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", - i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), + i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), + testUtilOutputOptionsName(data[i].output_options), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); - assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); + assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } } @@ -312,10 +332,11 @@ static void test_hrt(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - data[i].option_1, data[i].option_2, -1 /*option_3*/, data[i].output_options, - data[i].data, data[i].length, debug); + data[i].option_1, data[i].option_2, -1 /*option_3*/, data[i].output_options, + data[i].data, data[i].length, debug); expected_length = (int) strlen(data[i].expected); - expected_raw_length = data[i].expected_raw_length == -1 ? (int) strlen(data[i].expected_raw) : data[i].expected_raw_length; + expected_raw_length = data[i].expected_raw_length == -1 ? (int) strlen(data[i].expected_raw) + : data[i].expected_raw_length; ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 %s\n", i, ret, symbol->errtxt); @@ -429,8 +450,10 @@ static void test_input(const testCtx *const p_ctx) { /* 48*/ { BARCODE_CODABLOCKF, UNICODE_MODE | ESCAPE_MODE, -1, -1, "2610\\u00F2", -1, 0, 2, 101, 1, 1, "67 63 00 1A 0A 64 63 4B 6A 67 64 0B 64 52 33 26 64 6A", "Okapi data-fuzz-19.png" }, /* 49*/ { BARCODE_CODABLOCKF, DATA_MODE | ESCAPE_MODE, 7, -1, "*\\r\\xF2\\x82\\x82(\\x982\\x82\\x82*\\r\\xF2\\x82\\xA8\\x82\\x82\\x82\\x82", -1, 0, 7, 123, 0, 899, "(77) 67 62 45 0A 4D 64 64 52 63 35 6A 67 62 0B 65 42 65 42 08 63 43 6A 67 62 0C 65 58 12", "Okapi data-fuzz-20.png; BWIPP different encodation" }, /* 50*/ { BARCODE_CODABLOCKF, UNICODE_MODE | ESCAPE_MODE, -1, -1, "\\u0018\\u00F2", -1, 0, 2, 101, 0, 1, "67 62 40 58 65 62 52 16 6A 67 64 0B 63 64 38 30 30 6A", "Okapi data-fuzz-21.png; BWIPP different encodation" }, - /* 51*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, -1, "A99912345/$$52001510X3", -1, 0, 6, 101, 1, 1, "(54) 67 64 44 0B 21 19 19 3A 6A 67 63 2B 5B 17 2D 64 24 6A 67 64 0C 0F 04 04 15 16 6A 67", "" }, - /* 52*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, -1, "A99912345/$$520:1510X3", -1, ZINT_ERROR_INVALID_DATA, -1, -1, 1, 1, "Error 203: Invalid character at position 16 in input (alphanumerics, space and \"-.$/+%\" only)", "" }, + /* 51*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, -1, "\256^a\357\033\270\017,\274u$B\305\311\006\011]\273\025u\315\2638\263\333", -1, 0, 7, 123, 1, 899, "(77) 67 64 45 64 0E 3E 41 64 4F 33 6A 67 62 0B 5B 65 18 4F 0C 63 01 6A 67 64 0C 64 1C 55", "Misencodation of 0xB0-B9 (\260-\271) as FNC4 digit followed by digit as CodeC (found with 'test_random'" }, + /* 52*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, -1, "\356\237V\310\266767", -1, 0, 5, 101, 0, 899, "(45) 67 64 43 64 4E 63 64 57 6A 67 62 0B 65 5F 36 63 13 6A 67 64 0C 64 28 64 16 53 6A 67", "BWIPP example of above; BWIPP different encodation" }, + /* 53*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, -1, "A99912345/$$52001510X3", -1, 0, 6, 101, 1, 1, "(54) 67 64 44 0B 21 19 19 3A 6A 67 63 2B 5B 17 2D 64 24 6A 67 64 0C 0F 04 04 15 16 6A 67", "" }, + /* 54*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, -1, "A99912345/$$520:1510X3", -1, ZINT_ERROR_INVALID_DATA, -1, -1, 1, 1, "Error 203: Invalid character at position 16 in input (alphanumerics, space and \"-.$/+%\" only)", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -460,7 +483,8 @@ static void test_input(const testCtx *const p_ctx) { data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, \"%s\", %d, %s, %d, %d, %d, %d, \"%s\", \"%s\" },\n", @@ -470,23 +494,33 @@ static void test_input(const testCtx *const p_ctx) { testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -535,47 +569,47 @@ static void test_encode(const testCtx *const p_ctx) { /* 0*/ { BARCODE_CODABLOCKF, 1, -1, "AIM", 0, 1, 68, 1, "Same as CODE128 (not supported by BWIPP or ZXing-C++)", "11010010000101000110001100010001010111011000101110110001100011101011" }, - /* 1*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against tec-it", + /* 1*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010111011110100100111101100011101011" "11010000100101111011101011001110010111011110101111011101100001010011011101110111100101001100011101011" }, - /* 2*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against tec-it", + /* 2*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAA", 0, 3, 101, 1, "Defaults to rows 3, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101011001110010100011000101000110001110110010010010110000111000101101100011101011" }, - /* 3*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against tec-it", + /* 3*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101011001110010100011000101000110001010001100010111011110100111101001100011101011" "11010000100101111011101001101110010111011110101111011101110101100011101100100110010111001100011101011" }, - /* 4*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against tec-it", + /* 4*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAA", 0, 4, 101, 1, "Defaults to rows 4, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011" "11010000100101111011101001101110010100011000101000110001011110100010111011000100110000101100011101011" }, - /* 5*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against tec-it", + /* 5*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011" "11010000100101111011101001101110010100011000101000110001010001100010111011110111101001001100011101011" "11010000100101111011101001100111010111011110101111011101000110001010111101000110001010001100011101011" }, - /* 6*/ { BARCODE_CODABLOCKF, -1, 14, "AAAAAAAAAAAAAAA", 0, 2, 156, 1, "Rows 2, columns 14 (9 data); verified manually against tec-it", + /* 6*/ { BARCODE_CODABLOCKF, -1, 14, "AAAAAAAAAAAAAAA", 0, 2, 156, 1, "Rows 2, columns 14 (9 data); verified manually against TEC-IT", "110100001001011110111010100001100101000110001010001100010100011000101000110001010001100010100011000101000110001010001100010100011000110001000101100011101011" "110100001001011110111011000100100101000110001010001100010100011000101000110001010001100010100011000101110111101110111101011011000110111000101101100011101011" }, - /* 7*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against tec-it", + /* 7*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAA", 0, 5, 101, 1, "Defaults to rows 5, columns 9 (4 data); verified manually against TEC-IT", "11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011" "11010000100101111011101001101110010100011000101000110001010001100010100011000111101011101100011101011" "11010000100101111011101001100111010111011110101111011101011100011010001100010100011101101100011101011" }, - /* 8*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAAAAAAAAAAA", 0, 6, 112, 1, "Defaults to rows 6, columns 10 (5 data); verified manually against tec-it", + /* 8*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAAAAAAAAAAA", 0, 6, 112, 1, "Defaults to rows 6, columns 10 (5 data); verified manually against TEC-IT", "1101000010010111101110100001001101010001100010100011000101000110001010001100010100011000110110001101100011101011" "1101000010010111101110110001001001010001100010100011000101000110001010001100010100011000110010011101100011101011" "1101000010010111101110101100111001010001100010100011000101000110001010001100010100011000110011101001100011101011" @@ -607,12 +641,12 @@ static void test_encode(const testCtx *const p_ctx) { "110100001001011110111011100110010100111101001001111001011110100100111100101001111001001011011011110110111101101111011011010101111000111101010001100011101011" "110100001001011110111011011011000101000111101000101111010111011110101111011101011101111010111101110101110111101011100011011101101110101001100001100011101011" }, - /* 12*/ { BARCODE_HIBC_BLOCKF, 3, -1, "A123BJC5D6E71", 0, 3, 123, 0, "Verified manually against tec-it; differs from BWIPP (columns=6) which uses Code C for final 71 (same no. of codewords)", + /* 12*/ { BARCODE_HIBC_BLOCKF, 3, -1, "A123BJC5D6E71", 0, 3, 123, 0, "Verified manually against TEC-IT; differs from BWIPP (columns=6) which uses Code C for final 71 (same no. of codewords)", "110100001001011110111010010110000110001001001010001100010011100110110011100101100101110010001011000100100001101100011101011" "110100001001011110111011000100100101101110001000100011011011100100101100010001100111010010001101000111001001101100011101011" "110100001001011110111010110011100111011011101001110011011010001000101110111101011100011011001110100100100110001100011101011" }, - /* 13*/ { BARCODE_HIBC_BLOCKF, -1, -1, "$$52001510X3G", 0, 4, 101, 1, "tec-it differs as adds unnecessary Code C at end of 1st line", + /* 13*/ { BARCODE_HIBC_BLOCKF, -1, -1, "$$52001510X3G", 0, 4, 101, 1, "TEC-IT differs as adds unnecessary Code C at end of 1st line", "11010000100101111011101001000011011000100100100100011001001000110011011100100101110011001100011101011" "11010000100101110111101011000111011001001110110011011001101110100010111101110100001100101100011101011" "11010000100101111011101011001110010011101100111000101101100101110011010001000100100011001100011101011" @@ -758,21 +792,30 @@ static void test_fuzz(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", diff --git a/backend/tests/test_code.c b/backend/tests/test_code.c index 22a715f9..beeb8036 100644 --- a/backend/tests/test_code.c +++ b/backend/tests/test_code.c @@ -536,110 +536,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_CODE39, -1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+", 0, 1, 1130, "CODE39 85" }, - /* 1*/ { BARCODE_CODE39, -1, "123456ABCD", 0, 1, 155, "CODE39 10" }, - /* 2*/ { BARCODE_CODE93, -1, - "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !\"#$%&'()*+,-./0123456789ABCDEFGHIJ", - 0, 1, 1000, "CODE93 107 symbol chars" }, - /* 3*/ { BARCODE_CODE93, -1, "123456ABCD", 0, 1, 127, "CODE93 10" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -647,7 +543,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_code11.c b/backend/tests/test_code11.c index 88c0ec43..da6c3733 100644 --- a/backend/tests/test_code11.c +++ b/backend/tests/test_code11.c @@ -320,106 +320,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_CODE11, -1, "1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-", 0, 1, 966, "CODE11 121" }, - /* 1*/ { BARCODE_CODE11, -1, "1234567890-", 0, 1, 116, "CODE11 5" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -427,7 +327,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index b3ab292a..9c0755fe 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -121,29 +121,42 @@ static void test_large(const testCtx *const p_ctx) { if (data[i].length != -1) { testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); } else { strcpy(data_buf, data[i].pattern); } - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, data[i].output_options, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (data[i].output_options != -1 && (data[i].output_options & READER_INIT)) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), "READER_INIT not supported"); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), "READER_INIT not supported"); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data_buf, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data_buf, length, NULL, cmp_buf, sizeof(cmp_buf), + NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -297,10 +310,11 @@ static void test_hrt(const testCtx *const p_ctx) { memset(symbol->text, 0xDD, sizeof(symbol->text)); /* Detect non-NUL terminated HRT */ length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, data[i].output_options, - data[i].data, data[i].length, debug); + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, data[i].output_options, + data[i].data, data[i].length, debug); expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; - expected_raw_length = data[i].expected_raw_length == -1 ? (int) strlen(data[i].expected_raw) : data[i].expected_raw_length; + expected_raw_length = data[i].expected_raw_length == -1 ? (int) strlen(data[i].expected_raw) + : data[i].expected_raw_length; ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 %s\n", i, ret, symbol->errtxt); @@ -328,12 +342,18 @@ static void test_hrt(const testCtx *const p_ctx) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (data[i].symbology == BARCODE_HIBC_128 && not_sane(IS_NUM_F | IS_UPR_F | IS_SPC_F | IS_PLS_F | IS_MNS_F | IS_SIL_F, (const unsigned char *) data[i].data, length)) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), "BWIPP does not uppercase input"); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), "BWIPP does not uppercase input"); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -413,21 +433,28 @@ static void test_reader_init(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", - i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), + i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), + testUtilOutputOptionsName(data[i].output_options), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; @@ -621,6 +648,7 @@ static void test_input(const testCtx *const p_ctx) { /*138*/ { DATA_MODE, "1234\200", -1, 0, 90, 1, 899, "(8) 105 12 34 101 101 64 79 106", "StartC 12 34 CodeA FNC4 PAD" }, /*139*/ { UNICODE_MODE, "12é12é", -1, 0, 123, 0, 1, "(11) 105 12 100 100 73 17 18 100 73 17 106", "StartC 12 CodeB FNC4 é 1 2 FNC4 é; BWIPP different encodation (StartB)" }, /*140*/ { UNICODE_MODE, "1234é123456é", -1, 0, 167, 1, 1, "(15) 105 12 34 100 100 73 99 12 34 56 100 100 73 15 106", "StartC 12 34 CodeB FNC4 é CodeC 12 34 56 CodeB FNC4 é" }, + /*141*/ { DATA_MODE, "\256^a\357\033\270\017,\274u$B\305\311\006\011]\273\025u\315\2638\263\333", -1, 0, 453, 1, 899, "(41) 104 100 14 62 65 100 79 101 91 101 24 79 12 101 28 98 85 4 34 101 37 101 41 70 73 61", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -647,7 +675,9 @@ static void test_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_CODE128, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODE128, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); @@ -658,8 +688,10 @@ static void test_input(const testCtx *const p_ctx) { testUtilErrorName(ret), symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, symbol->errtxt, data[i].comment); } else { - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", i, symbol->errtxt, data[i].expected, symbol->width); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", + i, symbol->errtxt, data[i].expected, symbol->width); if (ret < ZINT_ERROR) { assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, @@ -667,16 +699,23 @@ static void test_input(const testCtx *const p_ctx) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -776,39 +815,56 @@ static void test_gs1_128_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_GS1_128, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_GS1_128, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); if (p_ctx->generate) { printf(" /*%3d*/ { %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), - testUtilErrorName(data[i].ret), symbol->width, data[i].bwipp_cmp, symbol->errtxt, data[i].comment); + i, testUtilInputModeName(data[i].input_mode), + testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), + symbol->width, data[i].bwipp_cmp, symbol->errtxt, data[i].comment); } else { - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", i, symbol->errtxt, data[i].expected, symbol->width); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", + i, symbol->errtxt, data[i].expected, symbol->width); if (ret < ZINT_ERROR) { - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (ret == ZINT_WARN_HRT_TRUNCATED) { - assert_nonzero((int) ustrlen(symbol->text) < (int) strlen(data[i].data), "i:%d len symbol->text(%s) %d >= %d (%s) (%s)\n", - i, symbol->text, (int) ustrlen(symbol->text), (int) strlen(data[i].data), data[i].data, symbol->errtxt); + assert_nonzero((int) ustrlen(symbol->text) < (int) strlen(data[i].data), + "i:%d len symbol->text(%s) %d >= %d (%s) (%s)\n", + i, symbol->text, (int) ustrlen(symbol->text), (int) strlen(data[i].data), data[i].data, + symbol->errtxt); } else { - assert_equal((int) ustrlen(symbol->text), (int) strlen(data[i].data), "i:%d len symbol->text(%s) %d != %d (%s, %s) (%s)\n", - i, symbol->text, (int) ustrlen(symbol->text), (int) strlen(data[i].data), testUtilErrorName(ret), data[i].data, symbol->errtxt); + assert_equal((int) ustrlen(symbol->text), (int) strlen(data[i].data), + "i:%d len symbol->text(%s) %d != %d (%s, %s) (%s)\n", + i, symbol->text, (int) ustrlen(symbol->text), (int) strlen(data[i].data), + testUtilErrorName(ret), data[i].data, symbol->errtxt); } if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -883,32 +939,45 @@ static void test_hibc_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_HIBC_128, UNICODE_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_HIBC_128, UNICODE_MODE, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), - testUtilErrorName(data[i].ret), symbol->width, data[i].bwipp_cmp, symbol->errtxt, data[i].comment); + testUtilErrorName(data[i].ret), symbol->width, data[i].bwipp_cmp, symbol->errtxt, + data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", i, symbol->errtxt, data[i].expected, symbol->width); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (width %d)\n", + i, symbol->errtxt, data[i].expected, symbol->width); if (ret < ZINT_ERROR) { - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -970,7 +1039,9 @@ static void test_nve18_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_NVE18, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_NVE18, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -1024,7 +1095,9 @@ static void test_ean14_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_EAN14, UNICODE_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_EAN14, UNICODE_MODE, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_2*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -1119,7 +1192,9 @@ static void test_dpd_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_DPD, UNICODE_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_DPD, UNICODE_MODE, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -1240,7 +1315,9 @@ static void test_upu_s10_input(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_UPU_S10, UNICODE_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_UPU_S10, UNICODE_MODE, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -1490,12 +1567,13 @@ static void test_encode(const testCtx *const p_ctx) { data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, \"%s\", %s, %d, %d, %d, %d, \"%s\",\n", - i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].option_2, - testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), + i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), + data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); @@ -1504,22 +1582,31 @@ static void test_encode(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -1548,112 +1635,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 10 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_CODE128, "123456ABCD123456ABCD123456ABCD123456ABCD123456ABCD123456ABCD", 0, 1, 618, "CODE128 60" }, - /* 1*/ { BARCODE_CODE128, "123456ABCD", 0, 1, 123, "CODE128 10" }, - /* 2*/ { BARCODE_GS1_128, "[01]09501101530003", 0, 1, 134, "GS1_128 (01)" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - #if 0 - 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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - #endif - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", - comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), - TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", - comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), - TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -1668,7 +1649,6 @@ int main(int argc, char *argv[]) { { "test_dpd_input", test_dpd_input }, { "test_upu_s10_input", test_upu_s10_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_common.c b/backend/tests/test_common.c index 2119bf21..3c189219 100644 --- a/backend/tests/test_common.c +++ b/backend/tests/test_common.c @@ -117,7 +117,8 @@ static void test_to_upper(const testCtx *const p_ctx) { buf[length] = '\0'; to_upper(buf, length); - assert_zero(strcmp((const char *) buf, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, buf, data[i].expected); + assert_zero(strcmp((const char *) buf, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, buf, data[i].expected); } testFinish(); @@ -359,7 +360,8 @@ static void test_not_sane_lookup(const testCtx *const p_ctx) { if (ret == 0) { int j; for (j = 0; j < length; j++) { - assert_equal(posns[j], data[i].posns[j], "i:%d posns[%d] %d != expected posns[%d] %d\n", i, j, posns[j], j, data[i].posns[j]); + assert_equal(posns[j], data[i].posns[j], "i:%d posns[%d] %d != expected posns[%d] %d\n", + i, j, posns[j], j, data[i].posns[j]); } } } @@ -407,7 +409,8 @@ static void test_errtxt(const testCtx *const p_ctx) { ret = errtxt(data[i].error_number, symbol, data[i].err_id, data[i].msg); assert_equal(ret, data[i].error_number, "i:%d ret %d != %d\n", i, ret, data[i].error_number); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } testFinish(); @@ -539,7 +542,8 @@ static void test_errtxtf(const testCtx *const p_ctx) { if (data[i].debug_test) symbol->debug |= ZINT_DEBUG_TEST; if (data[i].num_args == 0) { - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, NULL /*suppress -Wformat-security*/); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, + NULL /*suppress -Wformat-security*/); } else if (data[i].num_args == 1) { if (data[i].i_arg != -1) { ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg); @@ -551,29 +555,36 @@ static void test_errtxtf(const testCtx *const p_ctx) { } else if (data[i].num_args == 2) { if (data[i].i_arg != -1) { if (data[i].s_arg != NULL) { - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, data[i].s_arg); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, + data[i].s_arg); } else { - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, data[i].f_arg); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, + data[i].f_arg); } } else { assert_nonnull(data[i].s_arg, "i:%d num_args:%d data[i].s_arg NULL", i, data[i].num_args); - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].s_arg, data[i].f_arg); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].s_arg, + data[i].f_arg); } } else if (data[i].num_args == 3) { assert_nonnull(data[i].s_arg, "i:%d num_args:%d data[i].s_arg NULL", i, data[i].num_args); - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, data[i].s_arg, data[i].f_arg); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, data[i].i_arg, data[i].s_arg, + data[i].f_arg); } else if (data[i].num_args == 9) { /* Special case max, assuming 4th arg "%d", 5th arg "%s" */ assert_nonnull(data[i].s_arg, "i:%d num_args:%d data[i].s_arg NULL", i, data[i].num_args); - ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, 2100000001, 2100000002, 3333, data[i].i_arg, data[i].s_arg, 2100000006, 2100000007, 2100000008, 2100000009); + ret = errtxtf(data[i].error_number, symbol, data[i].err_id, data[i].fmt, 2100000001, 2100000002, 3333, + data[i].i_arg, data[i].s_arg, 2100000006, 2100000007, 2100000008, 2100000009); } else { assert_nonnull(NULL, "i:%d num_args:%d > 3 && != 9\n", i, data[i].num_args); } if (data[i].ret == -1) { - assert_equal(ret, data[i].error_number, "i:%d ret %d != %d (%s)\n", i, ret, data[i].error_number, symbol->errtxt); + assert_equal(ret, data[i].error_number, "i:%d ret %d != %d (%s)\n", + i, ret, data[i].error_number, symbol->errtxt); } else { assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } testFinish(); @@ -700,9 +711,11 @@ static void test_utf8_to_unicode(const testCtx *const p_ctx) { assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); if (ret == 0) { int j; - assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length); + assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", + i, ret_length, data[i].ret_length); for (j = 0; j < ret_length; j++) { - assert_equal(vals[j], data[i].expected_vals[j], "i:%d vals[%d] %04X != %04X\n", i, j, vals[j], data[i].expected_vals[j]); + assert_equal(vals[j], data[i].expected_vals[j], "i:%d vals[%d] %04X != %04X\n", + i, j, vals[j], data[i].expected_vals[j]); } } assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", @@ -920,7 +933,8 @@ static void test_hrt_cpy_cat_nochk(const testCtx *const p_ctx) { expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; - hrt_cpy_cat_nochk(symbol, TCU(data[i].source), data[i].length, data[i].separator, TCU(data[i].cat), data[i].cat_length); + hrt_cpy_cat_nochk(symbol, TCU(data[i].source), data[i].length, data[i].separator, TCU(data[i].cat), + data[i].cat_length); if (p_ctx->index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) { for (j = 0; j < symbol->text_length; j++) { @@ -1243,8 +1257,10 @@ static void test_rt_printf_256(const testCtx *const p_ctx) { if (data[i].num_args == 1) { ret = rt_printf_256(symbol, data[i].fmt, data[i].data1); + assert_zero(ret, "i:%d rt_printf_256 1 arg ret %d != 0\n", i, ret); } else if (data[i].num_args == 2) { ret = rt_printf_256(symbol, data[i].fmt, data[i].data1, data[i].data2); + assert_zero(ret, "i:%d rt_printf_256 2 args ret %d != 0\n", i, ret); } else { assert_zero(1, "i:%d, bad num_args\n", i); } @@ -1323,10 +1339,13 @@ static void test_set_height(const testCtx *const p_ctx) { } symbol->height = data[i].height; - ret = set_height(symbol, data[i].min_row_height, data[i].default_height, data[i].max_height, data[i].no_errtxt); + ret = set_height(symbol, data[i].min_row_height, data[i].default_height, data[i].max_height, + data[i].no_errtxt); assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); - assert_equal(symbol->height, data[i].expected_height, "i:%d symbol->height %g != %g\n", i, symbol->height, data[i].expected_height); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d errtxt %s != %s\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(symbol->height, data[i].expected_height, "i:%d symbol->height %g != %g\n", + i, symbol->height, data[i].expected_height); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d errtxt %s != %s\n", + i, symbol->errtxt, data[i].expected_errtxt); } testFinish(); @@ -1350,7 +1369,7 @@ static void test_debug_test_codeword_dump_int(const testCtx *const p_ctx) { const int data_size = ARRAY_SIZE(data); int i; - struct zint_symbol s_symbol; + struct zint_symbol s_symbol = {0}; struct zint_symbol *symbol = &s_symbol; testStart(p_ctx->func_name); @@ -1362,8 +1381,11 @@ static void test_debug_test_codeword_dump_int(const testCtx *const p_ctx) { if (testContinue(p_ctx, i)) continue; debug_test_codeword_dump_int(symbol, data[i].codewords, data[i].length); - assert_nonzero(strlen(symbol->errtxt) < 92, "i:%d strlen(%s) >= 92 (%d)\n", i, symbol->errtxt, (int) strlen(symbol->errtxt)); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (%d, %d)\n", i, symbol->errtxt, data[i].expected, (int) strlen(symbol->errtxt), (int) strlen(data[i].expected)); + assert_nonzero(strlen(symbol->errtxt) < 92, "i:%d strlen(%s) >= 92 (%d)\n", + i, symbol->errtxt, (int) strlen(symbol->errtxt)); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0 (%d, %d)\n", + i, symbol->errtxt, data[i].expected, (int) strlen(symbol->errtxt), + (int) strlen(data[i].expected)); } testFinish(); diff --git a/backend/tests/test_composite.c b/backend/tests/test_composite.c index 737cf706..b0794073 100644 --- a/backend/tests/test_composite.c +++ b/backend/tests/test_composite.c @@ -3599,96 +3599,6 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITERATIONS 1000 - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_1; - const char *data; - const char *composite; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_EANX_CC, 1, "123456789012", - "[91]123456789012345678901234567890123456789012345678901234", - 0, 11, 99, "58 chars CC-A" }, - /* 1*/ { BARCODE_UPCA_CC, 2, "12345678901", - "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[94]12345678901234567890123456789012345678901234567890", - 0, 48, 99, "336 chars CC-B" }, - /* 2*/ { BARCODE_GS1_128_CC, 3, "[01]12345678901231", - "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", - 0, 32, 205, "564 chars CC-C" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, composite_length, ret; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - struct zint_symbol *symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); - assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length); - strcpy(symbol->primary, data[i].data); - - composite_length = (int) strlen(data[i].composite); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(data[i].composite), composite_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 (p_ctx->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 */ @@ -3705,7 +3615,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_fuzz", test_fuzz }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_dmatrix.c b/backend/tests/test_dmatrix.c index c34c617b..2dfa3bae 100644 --- a/backend/tests/test_dmatrix.c +++ b/backend/tests/test_dmatrix.c @@ -398,10 +398,18 @@ static void test_large(const testCtx *const p_ctx) { testUtilEscape(data[i].pattern, (int) strlen(data[i].pattern), escaped, sizeof(escaped)), data[i].length, testUtilErrorName(ret), symbol->rows, symbol->width, data[i].zxingcpp_cmp, errtxt); + ZBarcode_Clear(symbol); - symbol->input_mode |= FAST_MODE; + length = testUtilSetSymbol(symbol, data[i].symbology, FAST_MODE /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); + if (data[i].structapp.count) { + symbol->structapp = data[i].structapp; + } + (void) ZBarcode_Encode(symbol, TCU(data_buf), length); - printf(" \"%s\", \"%s\" },\n", strcmp(errtxt, symbol->errtxt) != 0 ? symbol->errtxt : "", data[i].comment); + printf(" \"%s\", \"%s\" },\n", + strcmp(errtxt, symbol->errtxt) != 0 ? symbol->errtxt : "", data[i].comment); } else { assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -435,7 +443,13 @@ static void test_large(const testCtx *const p_ctx) { } ZBarcode_Clear(symbol); - symbol->input_mode |= FAST_MODE; + length = testUtilSetSymbol(symbol, data[i].symbology, FAST_MODE /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); + if (data[i].structapp.count) { + symbol->structapp = data[i].structapp; + } + ret = ZBarcode_Encode(symbol, TCU(data_buf), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -519,18 +533,26 @@ static void test_buffer(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_DATAMATRIX, data[i].input_mode, data[i].eci, -1 /*option_1*/, -1, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_DATAMATRIX, data[i].input_mode, data[i].eci, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[144 * 144 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), + NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -705,13 +727,16 @@ static void test_options(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); debug &= ~ZINT_DEBUG_TEST; /* Want real errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, + data[i].data, -1, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (width %d) (%s)\n", @@ -720,12 +745,18 @@ static void test_options(const testCtx *const p_ctx) { i, symbol->width, data[i].expected_width, symbol->errtxt); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[144 * 144 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -760,15 +791,26 @@ static void test_options(const testCtx *const p_ctx) { assert_zero(symbol->option_3, "i:%d symbol->option_3 %d != 0\n", i, symbol->option_3); /* Unchanged */ } - symbol->input_mode |= FAST_MODE; + ZBarcode_Clear(symbol); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | FAST_MODE, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, + data[i].data, -1, debug); + if (data[i].structapp.count) { + symbol->structapp = data[i].structapp; + } + ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode FAST_MODE ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode FAST_MODE ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n", + i, symbol->errtxt, data[i].expected_errtxt); ZBarcode_Delete(symbol); } @@ -817,10 +859,13 @@ static void test_reader_init(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", @@ -838,8 +883,10 @@ static void test_reader_init(const testCtx *const p_ctx) { char modules_dump[144 * 144 + 1]; assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), + NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -862,7 +909,8 @@ static void test_reader_init(const testCtx *const p_ctx) { escaped); } } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } ZBarcode_Delete(symbol); @@ -1180,7 +1228,8 @@ static void test_input(const testCtx *const p_ctx) { } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, %s, { %d, %d, \"%s\" }, \"%s\", %s, %d, %d, %d, %d, %d, \"%s\", \"%s\", %d },\n", @@ -1193,25 +1242,35 @@ static void test_input(const testCtx *const p_ctx) { data[i].bwipp_cmp, data[i].zxingcpp_cmp, symbol->errtxt, data[i].comment, data[i].expected_diff); } else { if (ret < ZINT_ERROR) { - assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci); - assert_equal(symbol->rows, data[i].expected_rows, "i:%d rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", + i, symbol->eci, data[i].expected_eci); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d width %d != %d\n", + i, symbol->width, data[i].expected_width); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[144 * 144 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -1235,9 +1294,11 @@ static void test_input(const testCtx *const p_ctx) { #ifdef ZINT_TEST_ENCODING if (ret < ZINT_ERROR) { - if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) + if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) + && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) && data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2 - && data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options + && data[i].option_3 == data[i - 1].option_3 + && data[i].output_options == data[i - 1].output_options && strcmp(data[i].data, data[i - 1].data) == 0) { unsigned char binary[2][2200]; int gs1; @@ -1246,10 +1307,12 @@ static void test_input(const testCtx *const p_ctx) { unsigned char reduced[1000]; unsigned char *text; const int last_seg = 1; + const int expected_rows_width = data[i].expected_rows * data[i].expected_width; + const int prev_expected_rows_width = data[i - 1].expected_rows * data[i - 1].expected_width; - assert_equal(data[i].expected_rows * data[i].expected_width <= data[i - 1].expected_rows * data[i - 1].expected_width, 1, - "i:%d data[i].expected_rows * data[i].expected_width %d > data[i - 1].expected_rows * data[i - 1].expected_width %d\n", i, - data[i].expected_rows * data[i].expected_width, data[i - 1].expected_rows * data[i - 1].expected_width); + assert_equal(expected_rows_width <= prev_expected_rows_width, 1, + "i:%d expected_rows_width %d > prev_expected_rows_width %d\n", + i, expected_rows_width, prev_expected_rows_width); if ((data[i].input_mode & 0x07) == GS1_MODE) { ret = gs1_verify(symbol, (unsigned char *) data[i].data, length, reduced, &length); @@ -1261,7 +1324,8 @@ static void test_input(const testCtx *const p_ctx) { binlen = 0; symbol->input_mode = data[i - 1].input_mode; symbol->option_2 = data[i].option_2 != -1 ? data[i].option_2 : 0; /* Restore option_2 */ - gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; + gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : + (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; ret = dm_encode_test(symbol, text, length, symbol->eci, last_seg, gs1, binary[0], &binlen); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); @@ -1269,17 +1333,20 @@ static void test_input(const testCtx *const p_ctx) { binlen = 0; symbol->input_mode = data[i].input_mode; - gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; + gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : + (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; symbol->option_2 = data[i].option_2 != -1 ? data[i].option_2 : 0; /* Restore option_2 */ ret = dm_encode_test(symbol, text, length, symbol->eci, last_seg, gs1, binary[1], &binlen); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[1] = binlen; - assert_equal(binlens[0], binlens[1] + data[i].expected_diff, "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", + assert_equal(binlens[0], binlens[1] + data[i].expected_diff, + "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", i, binlens[0], binlens[1] + data[i].expected_diff, binlens[1], data[i].expected_diff); if (data[i].expected_diff >= 0) { - assert_equal(binlens[1] <= binlens[0], 1, "i:%d binlens[1] %d > binlens[0] %d\n", i, binlens[1], binlens[0]); + assert_equal(binlens[1] <= binlens[0], 1, "i:%d binlens[1] %d > binlens[0] %d\n", + i, binlens[1], binlens[0]); } } } @@ -5777,22 +5844,31 @@ static void test_encode(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -5814,23 +5890,28 @@ static void test_encode(const testCtx *const p_ctx) { } #ifdef ZINT_TEST_ENCODING - if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) + if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) + && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) && data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2 - && data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options + && data[i].option_3 == data[i - 1].option_3 + && data[i].output_options == data[i - 1].output_options && strcmp(data[i].data, data[i - 1].data) == 0) { unsigned char binary[2][2200]; int gs1; int binlen; int binlens[2] = {0}; const int last_seg = 1; + const int expected_rows_width = data[i].expected_rows * data[i].expected_width; + const int prev_expected_rows_width = data[i - 1].expected_rows * data[i - 1].expected_width; - assert_equal(data[i].expected_rows * data[i].expected_width <= data[i - 1].expected_rows * data[i - 1].expected_width, 1, - "i:%d data[i].expected_rows * data[i].expected_width %d > data[i - 1].expected_rows * data[i - 1].expected_width %d\n", i, - data[i].expected_rows * data[i].expected_width, data[i - 1].expected_rows * data[i - 1].expected_width); + assert_equal(expected_rows_width <= prev_expected_rows_width, 1, + "i:%d expected_rows_width %d > prev_expected_rows_width %d\n", i, + expected_rows_width, prev_expected_rows_width); binlen = 0; symbol->input_mode = data[i - 1].input_mode; - gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; + gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : + (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[0], &binlen); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); @@ -5839,14 +5920,16 @@ static void test_encode(const testCtx *const p_ctx) { binlen = 0; symbol->input_mode = data[i].input_mode; - gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; + gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : + (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[1], &binlen); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); binlens[1] = binlen; - assert_equal(binlens[1] <= binlens[0], 1, "i:%d binlens[1] %d > binlens[0] %d\n", i, binlens[1], binlens[0]); + assert_equal(binlens[1] <= binlens[0], 1, "i:%d binlens[1] %d > binlens[0] %d\n", + i, binlens[1], binlens[0]); assert_equal(binlens[0], binlens[1] + data[i].expected_diff, "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", i, binlens[0], binlens[1] + data[i].expected_diff, binlens[1], data[i].expected_diff); @@ -6198,8 +6281,9 @@ static void test_encode_segs(const testCtx *const p_ctx) { char cmp_buf[32768]; char cmp_msg[1024]; - int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ - int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ + /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); testStartSymbol(p_ctx->func_name, &symbol); @@ -6211,15 +6295,16 @@ static void test_encode_segs(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, data[i].option_2, data[i].option_3, data[i].output_options, - NULL, 0, debug); + -1 /*option_1*/, data[i].option_2, data[i].option_3, data[i].output_options, + NULL, 0, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; @@ -6232,9 +6317,12 @@ static void test_encode_segs(const testCtx *const p_ctx) { testUtilOutputOptionsName(data[i].output_options), data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, - testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, - testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, - testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, + testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), + data[i].segs[0].length, data[i].segs[0].eci, + testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), + data[i].segs[1].length, data[i].segs[1].eci, + testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), + data[i].segs[2].length, data[i].segs[2].eci, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); @@ -6242,25 +6330,34 @@ static void test_encode_segs(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); - assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].segs, + seg_count, NULL, cmp_buf, sizeof(cmp_buf)); + assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } - if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) { + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, + data[i].segs[0].length, debug)) { if (data[i].input_mode == DATA_MODE) { if (debug & ZINT_DEBUG_TEST_PRINT) { printf("i:%d %s multiple segments in DATA_MODE not currently supported for ZXing-C++ testing\n", @@ -6269,14 +6366,18 @@ static void test_encode_segs(const testCtx *const p_ctx) { } else { int cmp_len, ret_len; char modules_dump[144 * 144 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, - modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, + data[i].segs[0].length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), + &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count, NULL /*primary*/, escaped, &ret_len); - assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + assert_zero(ret, + "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); } @@ -7524,26 +7625,33 @@ static void test_minimalenc(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, + data[i].data, data[i].length, debug); binlen = 0; symbol->input_mode |= FAST_MODE; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[0], &binlen); - assert_equal(ret, data[i].ret, "i:%d dm_encode() FAST_MODE ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[0], + &binlen); + assert_equal(ret, data[i].ret, "i:%d dm_encode() FAST_MODE ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); binlens[0] = binlen; binlen = 0; symbol->input_mode &= ~FAST_MODE; gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1; - ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[1], &binlen); - assert_equal(ret, data[i].ret, "i:%d dm_encode() minimal ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + ret = dm_encode_test(symbol, (unsigned char *) data[i].data, length, symbol->eci, last_seg, gs1, binary[1], + &binlen); + assert_equal(ret, data[i].ret, "i:%d dm_encode() minimal ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); binlens[1] = binlen; fflush(stdout); - assert_equal(binlens[0], binlens[1] + data[i].expected_diff, "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", + assert_equal(binlens[0], binlens[1] + data[i].expected_diff, + "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", i, binlens[0], binlens[1] + data[i].expected_diff, binlens[1], data[i].expected_diff); if (debug & ZINT_DEBUG_TEST_PRINT) { @@ -7563,180 +7671,6 @@ static void test_minimalenc(const testCtx *const p_ctx) { } #endif -#include - -#if 1 -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#else -#define TEST_PERF_ITERATIONS 100 /* For valgrind */ -#endif -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_2; - int option_3; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_DATAMATRIX, FAST_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" - "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" - "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" - "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" - "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" - "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", - 0, 96, 96, "960 chars, text/numeric" }, - /* 1*/ { BARCODE_DATAMATRIX, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" - "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" - "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" - "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" - "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" - "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", - 0, 96, 96, "960 chars, text/numeric" }, - /* 2*/ { BARCODE_DATAMATRIX, DATA_MODE | FAST_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, 120, 120, "960 chars, byte" }, - /* 3*/ { BARCODE_DATAMATRIX, 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, 120, 120, "960 chars, byte" }, - /* 4*/ { BARCODE_DATAMATRIX, FAST_MODE, -1, -1, "https://example.com/01/09506000134369", 0, 22, 22, "37 chars, text/numeric" }, - /* 5*/ { BARCODE_DATAMATRIX, -1, -1, -1, "https://example.com/01/09506000134369", 0, 22, 22, "37 chars, text/numeric" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -7752,7 +7686,6 @@ int main(int argc, char *argv[]) { #ifdef ZINT_TEST_ENCODING { "test_minimalenc", test_minimalenc }, #endif - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_dotcode.c b/backend/tests/test_dotcode.c index 89bd765e..7397677f 100644 --- a/backend/tests/test_dotcode.c +++ b/backend/tests/test_dotcode.c @@ -46,9 +46,12 @@ static void test_large(const testCtx *const p_ctx) { /* 0*/ { 200, '0', 2940, 0, "" }, /* 2940 largest Code Set C data that fits in 200x199 HxW */ /* 1*/ { 200, '0', 2941, ZINT_ERROR_INVALID_OPTION, "Error 528: Resulting symbol height '201' is too large (maximum 200)" }, /* 2*/ { 200, '9', 200, 0, "" }, /* Changes a number of mask scores re pre-Rev. 4 version, but best score still the same (7) */ - /* 3*/ { 201, '0', 2940, ZINT_ERROR_INVALID_OPTION, "Error 528: Resulting symbol width '201' is too large (maximum 200)" }, - /* 4*/ { 201, '0', 2974, ZINT_ERROR_INVALID_OPTION, "Error 526: Resulting symbol size '202x201' (HxW) is too large (maximum 200x200)" }, /* Height > 200 also */ - /* 5*/ { 30, '\001', 71, 0, "" }, /* Codeword length 72, ECC length 39, for ND + 1 == 112 */ + /* 3*/ { 200, '0', 2974, ZINT_ERROR_INVALID_OPTION, "Error 528: Resulting symbol height '203' is too large (maximum 200)" }, /* Width > 200 also */ + /* 4*/ { 200, 'A', 1470, 0, "" }, + /* 5*/ { 200, 'A', 1471, ZINT_ERROR_INVALID_OPTION, "Error 528: Resulting symbol height '201' is too large (maximum 200)" }, + /* 6*/ { 200, '\240', 1225, 0, "" }, + /* 7*/ { 200, '\240', 1226, ZINT_ERROR_INVALID_OPTION, "Error 528: Resulting symbol height '201' is too large (maximum 200)" }, + /* 8*/ { 30, '\001', 71, 0, "" }, /* Codeword length 72, ECC length 39, for ND + 1 == 112 */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -105,11 +108,11 @@ static void test_options(const testCtx *const p_ctx) { /* 2*/ { -1, -1, -1, 19, -1, { 0, 0, "" }, "1234567890", 0, 12, 19, "", 19, 2 << 8 }, /* 3*/ { -1, -1, -1, 12, -1, { 0, 0, "" }, "1234567890", 0, 19, 12, "", 12, 2 << 8 }, /* 4*/ { -1, -1, -1, 5, -1, { 0, 0, "" }, "1234567890", 0, 44, 5, "", 5, 6 << 8 }, - /* 5*/ { -1, -1, -1, 4, -1, { 0, 0, "" }, "1234567890", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 529: Resulting symbol width '4' is too small (minimum 5)", 4, 0 }, /* Cols < 5 */ - /* 6*/ { -1, -1, -1, 200, -1, { 0, 0, "" }, "1234567890", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 529: Resulting symbol height '3' is too small (minimum 5)", 200, 0 }, /* Not enough data - height 3 too small */ + /* 5*/ { -1, -1, -1, 4, -1, { 0, 0, "" }, "1234567890", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 527: Number of columns '4' is out of range (5 to 200)", 4, 0 }, /* Cols < 5 */ + /* 6*/ { -1, -1, -1, 200, -1, { 0, 0, "" }, "1234567890", 0, 5, 200, "", 200, 7 << 8 }, /* Note used to fail - now sets height to at least 5 */ /* 7*/ { -1, -1, -1, 200, -1, { 0, 0, "" }, "1234567890123456789012345678901234567890", 0, 5, 200, "", 200, 7 << 8 }, /* Cols 200 max */ /* 8*/ { -1, -1, -1, 200, -1, { 0, 0, "" }, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 7, 200, "", 200, 4 << 8 }, - /* 9*/ { -1, -1, -1, 201, -1, { 0, 0, "" }, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 528: Resulting symbol width '201' is too large (maximum 200)", 201, 0 }, + /* 9*/ { -1, -1, -1, 201, -1, { 0, 0, "" }, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 527: Number of columns '201' is out of range (5 to 200)", 201, 0 }, /* 10*/ { -1, -1, -1, -1, 10 << 8, { 0, 0, "" }, "1", 0, 9, 14, "", 14, 1 << 8 }, /* Mask > 8 + 1 ignored */ /* 11*/ { -1, -1, -1, -1, 8 << 8, { 0, 0, "" }, "1", 0, 9, 14, "", 14, 8 << 8 }, /* 12*/ { -1, -1, -1, 19, -1, { 0, 0, "" }, "ABCDE", 0, 12, 19, "", 19, 3 << 8 }, @@ -1879,84 +1882,6 @@ static void test_generate(const testCtx *const p_ctx) { printf("\n };\n"); } -#include - -#define TEST_PERF_ITERATIONS 1000 - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_DOTCODE, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" - "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" - "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" - "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" - "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" - "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", - 0, 124, 185, "960 chars, text/numeric" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - struct zint_symbol *symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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 (p_ctx->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 */ @@ -1969,7 +1894,6 @@ int main(int argc, char *argv[]) { { "test_rt_segs", test_rt_segs }, { "test_fuzz", test_fuzz }, { "test_generate", test_generate }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_gridmtx.c b/backend/tests/test_gridmtx.c index f2f9ef7d..470758cb 100644 --- a/backend/tests/test_gridmtx.c +++ b/backend/tests/test_gridmtx.c @@ -1091,92 +1091,6 @@ static void test_rt_segs(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITERATIONS 1000 - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, -1, -1, - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738", - 0, 66, 66, "97 chars, mixed modes" }, - /* 1*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, -1, -1, - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" - "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738", - 0, 162, 162, "970 chars, mixed modes" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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 (p_ctx->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 */ @@ -1187,7 +1101,6 @@ int main(int argc, char *argv[]) { { "test_encode_segs", test_encode_segs }, { "test_rt", test_rt }, { "test_rt_segs", test_rt_segs }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_gs1.c b/backend/tests/test_gs1.c index b6b14f18..cd131580 100644 --- a/backend/tests/test_gs1.c +++ b/backend/tests/test_gs1.c @@ -2346,7 +2346,7 @@ static void test_input_mode(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - struct zint_symbol previous_symbol; + struct zint_symbol *previous_symbol = NULL; testStartSymbol(p_ctx->func_name, &symbol); @@ -2357,18 +2357,21 @@ static void test_input_mode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->index == -1 && data[i].compare_previous) { - ret = testUtilSymbolCmp(symbol, &previous_symbol); + ret = testUtilSymbolCmp(symbol, previous_symbol); assert_zero(ret, "i:%d testUtilSymbolCmp ret %d != 0\n", i, ret); } - memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); - - ZBarcode_Delete(symbol); + ZBarcode_Delete(previous_symbol); + previous_symbol = symbol; } + ZBarcode_Delete(previous_symbol); testFinish(); } diff --git a/backend/tests/test_hanxin.c b/backend/tests/test_hanxin.c index a841c994..34c2f49e 100644 --- a/backend/tests/test_hanxin.c +++ b/backend/tests/test_hanxin.c @@ -3839,108 +3839,6 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITERATIONS 1000 - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", - ZINT_WARN_NONCOMPLIANT, 43, 43, "98 chars, Region One and Text" }, - /* 1*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", - ZINT_WARN_NONCOMPLIANT, 121, 121, "980 chars, Region One and Text" }, - /* 2*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" - "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", - ZINT_WARN_NONCOMPLIANT, 147, 147, "1470 chars, Region One and Text" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - struct zint_symbol *symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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 (p_ctx->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 */ @@ -3952,7 +3850,6 @@ int main(int argc, char *argv[]) { { "test_rt", test_rt }, { "test_rt_segs", test_rt_segs }, { "test_fuzz", test_fuzz }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 02eddfed..5c4e5aa5 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -229,7 +229,9 @@ static void test_checks(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, + data[i].option_1, -1, -1, -1 /*output_options*/, + data[i].data, data[i].length, debug); if (data[i].height) { symbol->height = data[i].height; } @@ -259,15 +261,19 @@ static void test_checks(const testCtx *const p_ctx) { } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", + i, data[i].symbology, ret, data[i].ret, symbol->errtxt); ret = strcmp(symbol->errtxt, data[i].expected); - assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret); + assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", + i, data[i].symbology, symbol->errtxt, data[i].expected, ret); if (data[i].expected_symbology == -1) { - assert_equal(symbol->symbology, data[i].symbology, "i:%d symbol->symbology %d != original %d\n", i, symbol->symbology, data[i].symbology); + assert_equal(symbol->symbology, data[i].symbology, "i:%d symbol->symbology %d != original %d\n", + i, symbol->symbology, data[i].symbology); } else { - assert_equal(symbol->symbology, data[i].expected_symbology, "i:%d symbol->symbology %d != expected %d\n", i, symbol->symbology, data[i].expected_symbology); + assert_equal(symbol->symbology, data[i].expected_symbology, "i:%d symbol->symbology %d != expected %d\n", + i, symbol->symbology, data[i].expected_symbology); } ZBarcode_Delete(symbol); @@ -322,16 +328,20 @@ static void test_checks_segs(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, -1, -1, -1 /*output_options*/, NULL, 0, debug); + testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, + data[i].option_1, -1, -1, -1 /*output_options*/, + NULL, 0, debug); if (data[i].warn_level != -1) { symbol->warn_level = data[i].warn_level; } ret = ZBarcode_Encode_Segs(symbol, data[i].segs, data[i].seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs(%d) ret %d != %d (%s)\n", + i, data[i].symbology, ret, data[i].ret, symbol->errtxt); ret = strcmp(symbol->errtxt, data[i].expected); - assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret); + assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", + i, data[i].symbology, symbol->errtxt, data[i].expected, ret); ZBarcode_Delete(symbol); } @@ -383,13 +393,17 @@ static void test_input_data(const testCtx *const p_ctx) { } else { text = data[i].data; } - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, text, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + text, -1, debug); ret = ZBarcode_Encode(symbol, TCU(text), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", + i, data[i].symbology, ret, data[i].ret, symbol->errtxt); ret = strcmp(symbol->errtxt, data[i].expected); - assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret); + assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", + i, data[i].symbology, symbol->errtxt, data[i].expected, ret); ZBarcode_Delete(symbol); } @@ -409,8 +423,10 @@ static void test_input_data(const testCtx *const p_ctx) { data_buf[ZINT_MAX_DATA_LEN + 1] = 'n'; ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, ZINT_MAX_DATA_LEN + 2); - assert_equal(ret, expected_ret, "ZBarcode_Encode(%d) ret %d != %d (%s)\n", symbol->symbology, ret, expected_ret, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, expected_errtxt[0]), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, expected_errtxt[0]); + assert_equal(ret, expected_ret, "ZBarcode_Encode(%d) ret %d != %d (%s)\n", + symbol->symbology, ret, expected_ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, expected_errtxt[0]), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, expected_errtxt[0]); /* Passes de-escape loop, caught by `code128()` */ symbol->errtxt[0] = '\0'; @@ -418,8 +434,10 @@ static void test_input_data(const testCtx *const p_ctx) { data_buf[ZINT_MAX_DATA_LEN - 1] = 'n'; ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, ZINT_MAX_DATA_LEN); - assert_equal(ret, expected_ret, "ZBarcode_Encode(%d) ret %d != %d (%s)\n", symbol->symbology, ret, expected_ret, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, expected_errtxt[1]), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, expected_errtxt[1]); + assert_equal(ret, expected_ret, "ZBarcode_Encode(%d) ret %d != %d (%s)\n", + symbol->symbology, ret, expected_ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, expected_errtxt[1]), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, expected_errtxt[1]); ZBarcode_Delete(symbol); } @@ -585,12 +603,17 @@ static void test_input_mode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, + -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", i, symbol->input_mode, data[i].expected_input_mode); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d ZBarcode_Encode strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", + i, symbol->input_mode, data[i].expected_input_mode); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d ZBarcode_Encode strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); ZBarcode_Delete(symbol); } @@ -706,7 +729,7 @@ static void test_escape_char_process(const testCtx *const p_ctx) { char escaped[1024]; char escaped_composite[1024]; - struct zint_symbol previous_symbol; + struct zint_symbol *previous_symbol = NULL; const char *input_filename = "test_escape.txt"; const char *text; @@ -729,28 +752,34 @@ static void test_escape_char_process(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, text, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + text, -1, debug); ret = ZBarcode_Encode(symbol, TCU(text), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, \"%s\", \"%s\", %s, %d, \"%s\", %d, \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilEscape(data[i].data, length, escaped, ARRAY_SIZE(escaped)), - testUtilEscape(data[i].composite, (int) strlen(data[i].composite), escaped_composite, ARRAY_SIZE(escaped_composite)), - testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].compare_previous, data[i].comment); + testUtilEscape(data[i].composite, (int) strlen(data[i].composite), escaped_composite, + ARRAY_SIZE(escaped_composite)), + testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].compare_previous, + data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (p_ctx->index == -1 && data[i].compare_previous) { - ret = testUtilSymbolCmp(symbol, &previous_symbol); + ret = testUtilSymbolCmp(symbol, previous_symbol); assert_zero(ret, "i:%d testUtilSymbolCmp ret %d != 0\n", i, ret); } } - memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); if (ret < ZINT_ERROR && !data[i].composite[0]) { /* Test from input file */ @@ -759,7 +788,8 @@ static void test_escape_char_process(const testCtx *const p_ctx) { fp = testUtilOpen(input_filename, "wb"); assert_nonnull(fp, "i:%d testUtilOpen(%s) failed\n", i, input_filename); - assert_notequal(fputs(data[i].data, fp), EOF, "i%d fputs(%s) failed == EOF (%d)\n", i, data[i].data, ferror(fp)); + assert_notequal(fputs(data[i].data, fp), EOF, "i%d fputs(%s) failed == EOF (%d)\n", + i, data[i].data, ferror(fp)); assert_zero(fclose(fp), "i%d fclose() failed\n", i); symbol2 = ZBarcode_Create(); @@ -767,23 +797,30 @@ static void test_escape_char_process(const testCtx *const p_ctx) { symbol2->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - (void) testUtilSetSymbol(symbol2, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + (void) testUtilSetSymbol(symbol2, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode_File(symbol2, input_filename); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_File ret %d != %d (%s)\n", i, ret, data[i].ret, symbol2->errtxt); - assert_zero(strcmp(symbol2->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol2->errtxt, data[i].expected); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_File ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol2->errtxt); + assert_zero(strcmp(symbol2->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol2->errtxt, data[i].expected); ret = testUtilSymbolCmp(symbol2, symbol); assert_zero(ret, "i:%d testUtilSymbolCmp symbol2 ret %d != 0\n", i, ret); - assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); + assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input_filename, errno, strerror(errno)); ZBarcode_Delete(symbol2); } } - ZBarcode_Delete(symbol); + ZBarcode_Delete(previous_symbol); + previous_symbol = symbol; } + ZBarcode_Delete(previous_symbol); testFinish(); } @@ -829,18 +866,24 @@ static void test_escape_char_process_test(const testCtx *const p_ctx) { escaped_len = length; ret = escape_char_process_test(symbol, (unsigned char *) data[i].data, &escaped_len, NULL); - assert_equal(ret, data[i].ret, "i:%d escape_char_process_test(NULL) ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(escaped_len, data[i].expected_len, "i:%d NULL escaped_len %d != %d\n", i, escaped_len, data[i].expected_len); + assert_equal(ret, data[i].ret, "i:%d escape_char_process_test(NULL) ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(escaped_len, data[i].expected_len, "i:%d NULL escaped_len %d != %d\n", + i, escaped_len, data[i].expected_len); memset(escaped, 0xDD, sizeof(escaped)); escaped_len = length; - ret = escape_char_process_test(symbol, (unsigned char *) data[i].data, &escaped_len, (unsigned char *) escaped); - assert_equal(ret, data[i].ret, "i:%d escape_char_process_test(escaped) ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(escaped_len, data[i].expected_len, "i:%d escaped escaped_len %d != %d\n", i, escaped_len, data[i].expected_len); + ret = escape_char_process_test(symbol, (unsigned char *) data[i].data, &escaped_len, + (unsigned char *) escaped); + assert_equal(ret, data[i].ret, "i:%d escape_char_process_test(escaped) ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(escaped_len, data[i].expected_len, "i:%d escaped escaped_len %d != %d\n", + i, escaped_len, data[i].expected_len); assert_zero(memcmp(escaped, data[i].expected, escaped_len), "i:%d memcmp() != 0\n", i); - assert_zero(escaped[escaped_len], "i:%d escaped[%d] not NUL-terminated (0x%X)\n", i, escaped_len, escaped[escaped_len]); + assert_zero(escaped[escaped_len], "i:%d escaped[%d] not NUL-terminated (0x%X)\n", + i, escaped_len, escaped[escaped_len]); } testFinish(); @@ -856,13 +899,13 @@ static void test_cap(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_CODE128, ZINT_CAP_HRT, ZINT_CAP_HRT }, - /* 1*/ { BARCODE_CODE128, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_GS1, ZINT_CAP_HRT | ZINT_CAP_STACKABLE }, - /* 2*/ { BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE, ZINT_CAP_ECI | ZINT_CAP_READER_INIT }, + /* 1*/ { BARCODE_CODE128, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_GS1 | ZINT_CAP_BINDABLE, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_BINDABLE }, + /* 2*/ { BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_BINDABLE, ZINT_CAP_ECI | ZINT_CAP_READER_INIT }, /* 3*/ { BARCODE_QRCODE, ZINT_CAP_HRT | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP }, /* 4*/ { BARCODE_EANX_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, /* 5*/ { BARCODE_HANXIN, ZINT_CAP_DOTTY | ZINT_CAP_QUIET_ZONES | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK }, /* 6*/ { BARCODE_CODE11, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_COMPLIANT_HEIGHT, 0 }, - /* 7*/ { BARCODE_POSTNET, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_COMPOSITE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP, 0 }, + /* 7*/ { BARCODE_POSTNET, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_COMPOSITE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP | ZINT_CAP_BINDABLE, 0 }, /* 8*/ { 0, 0, 0 }, }; const int data_size = ARRAY_SIZE(data); @@ -876,7 +919,8 @@ static void test_cap(const testCtx *const p_ctx) { if (testContinue(p_ctx, i)) continue; uret = ZBarcode_Cap(data[i].symbology, data[i].cap_flag); - assert_equal(uret, data[i].expected, "i:%d ZBarcode_Cap(%s, 0x%X) 0x%X != 0x%X\n", i, testUtilBarcodeName(data[i].symbology), data[i].cap_flag, uret, data[i].expected); + assert_equal(uret, data[i].expected, "i:%d ZBarcode_Cap(%s, 0x%X) 0x%X != 0x%X\n", + i, testUtilBarcodeName(data[i].symbology), data[i].cap_flag, uret, data[i].expected); } testFinish(); @@ -966,11 +1010,14 @@ static void test_cap_compliant_height(const testCtx *const p_ctx) { case BARCODE_BC412: case BARCODE_DXFILMEDGE: /* Make sure ZINT_CAP_COMPLIANT_HEIGHT set for those that have it */ - assert_equal(uret, ZINT_CAP_COMPLIANT_HEIGHT, "symbol_id %d (%s) uret 0x%X != ZINT_CAP_COMPLIANT_HEIGHT\n", symbol_id, testUtilBarcodeName(symbol_id), uret); + assert_equal(uret, ZINT_CAP_COMPLIANT_HEIGHT, + "symbol_id %d (%s) uret 0x%X != ZINT_CAP_COMPLIANT_HEIGHT\n", + symbol_id, testUtilBarcodeName(symbol_id), uret); break; default: /* And not set for those that don't */ - assert_zero(uret, "symbol_id %d (%s) uret 0x%X non-zero\n", symbol_id, testUtilBarcodeName(symbol_id), uret); + assert_zero(uret, "symbol_id %d (%s) uret 0x%X non-zero\n", + symbol_id, testUtilBarcodeName(symbol_id), uret); break; } } @@ -978,6 +1025,290 @@ static void test_cap_compliant_height(const testCtx *const p_ctx) { testFinish(); } +struct min_item { + int symbology; + const char *data; +}; +static const struct min_item min_data[] = { + /* 0*/ { BARCODE_CODE11, "1" }, + /* 1*/ { BARCODE_C25STANDARD, "1" }, + /* 2*/ { BARCODE_C25INTER, "1" }, + /* 3*/ { BARCODE_C25IATA, "1" }, + /* 4*/ { BARCODE_C25LOGIC, "1" }, + /* 5*/ { BARCODE_C25IND, "1" }, + /* 6*/ { BARCODE_CODE39, "1" }, + /* 7*/ { BARCODE_EXCODE39, "1" }, + /* 8*/ { BARCODE_EANX, "1" }, + /* 9*/ { BARCODE_EANX_CHK, "1" }, + /* 10*/ { BARCODE_GS1_128, "[01]12345678901231" }, + /* 11*/ { BARCODE_CODABAR, "A0B" }, + /* 12*/ { BARCODE_CODE128, "1" }, + /* 13*/ { BARCODE_DPLEIT, "1" }, + /* 14*/ { BARCODE_DPIDENT, "1" }, + /* 15*/ { BARCODE_CODE16K, "1" }, + /* 16*/ { BARCODE_CODE49, "1" }, + /* 17*/ { BARCODE_CODE93, "1" }, + /* 18*/ { BARCODE_FLAT, "1" }, + /* 19*/ { BARCODE_DBAR_OMN, "1" }, + /* 20*/ { BARCODE_DBAR_LTD, "1" }, + /* 21*/ { BARCODE_DBAR_EXP, "[01]12345678901231" }, + /* 22*/ { BARCODE_TELEPEN, "1" }, + /* 23*/ { BARCODE_UPCA, "1" }, + /* 24*/ { BARCODE_UPCE, "1" }, + /* 25*/ { BARCODE_POSTNET, "12345678901" }, + /* 26*/ { BARCODE_MSI_PLESSEY, "1" }, + /* 27*/ { BARCODE_FIM, "A" }, + /* 28*/ { BARCODE_LOGMARS, "1" }, + /* 29*/ { BARCODE_PHARMA, "3" }, + /* 30*/ { BARCODE_PZN, "1" }, + /* 31*/ { BARCODE_PHARMA_TWO, "4" }, + /* 32*/ { BARCODE_CEPNET, "12345678" }, + /* 33*/ { BARCODE_PDF417, "1" }, + /* 34*/ { BARCODE_PDF417COMP, "1" }, + /* 35*/ { BARCODE_MAXICODE, "1" }, + /* 36*/ { BARCODE_QRCODE, "1" }, + /* 37*/ { BARCODE_CODE128AB, "1" }, + /* 38*/ { BARCODE_AUSPOST, "12345678901234567890123" }, + /* 39*/ { BARCODE_AUSREPLY, "12345678" }, + /* 40*/ { BARCODE_AUSROUTE, "12345678" }, + /* 41*/ { BARCODE_AUSREDIRECT, "12345678" }, + /* 42*/ { BARCODE_ISBNX, "123456789" }, + /* 43*/ { BARCODE_RM4SCC, "1" }, + /* 44*/ { BARCODE_DATAMATRIX, "1" }, + /* 45*/ { BARCODE_EAN14, "1" }, + /* 46*/ { BARCODE_VIN, "12345678701234567" }, + /* 47*/ { BARCODE_CODABLOCKF, "1" }, + /* 48*/ { BARCODE_NVE18, "1" }, + /* 49*/ { BARCODE_JAPANPOST, "1" }, + /* 50*/ { BARCODE_KOREAPOST, "1" }, + /* 51*/ { BARCODE_DBAR_STK, "1" }, + /* 52*/ { BARCODE_DBAR_OMNSTK, "1" }, + /* 53*/ { BARCODE_DBAR_EXPSTK, "[01]12345678901231" }, + /* 54*/ { BARCODE_PLANET, "12345678901" }, + /* 55*/ { BARCODE_MICROPDF417, "1" }, + /* 56*/ { BARCODE_USPS_IMAIL, "12345678901234567890" }, + /* 57*/ { BARCODE_PLESSEY, "1" }, + /* 58*/ { BARCODE_TELEPEN_NUM, "1" }, + /* 59*/ { BARCODE_ITF14, "1" }, + /* 60*/ { BARCODE_KIX, "1" }, + /* 61*/ { BARCODE_AZTEC, "1" }, + /* 62*/ { BARCODE_DAFT, "D" }, + /* 63*/ { BARCODE_DPD, "0123456789012345678901234567" }, + /* 64*/ { BARCODE_MICROQR, "1" }, + /* 65*/ { BARCODE_HIBC_128, "1" }, + /* 66*/ { BARCODE_HIBC_39, "1" }, + /* 67*/ { BARCODE_HIBC_DM, "1" }, + /* 68*/ { BARCODE_HIBC_QR, "1" }, + /* 69*/ { BARCODE_HIBC_PDF, "1" }, + /* 70*/ { BARCODE_HIBC_MICPDF, "1" }, + /* 71*/ { BARCODE_HIBC_BLOCKF, "1" }, + /* 72*/ { BARCODE_HIBC_AZTEC, "1" }, + /* 73*/ { BARCODE_DOTCODE, "1" }, + /* 74*/ { BARCODE_HANXIN, "1" }, + /* 75*/ { BARCODE_MAILMARK_2D, "012100123412345678AB19XY1A 0" }, + /* 76*/ { BARCODE_UPU_S10, "EE876543216CA" }, + /* 77*/ { BARCODE_MAILMARK_4S, "01000000000000000AA00AA0A" }, + /* 78*/ { BARCODE_AZRUNE, "1" }, + /* 79*/ { BARCODE_CODE32, "1" }, + /* 80*/ { BARCODE_EANX_CC, "1" }, + /* 81*/ { BARCODE_GS1_128_CC, "[01]12345678901231" }, + /* 82*/ { BARCODE_DBAR_OMN_CC, "1" }, + /* 83*/ { BARCODE_DBAR_LTD_CC, "1" }, + /* 84*/ { BARCODE_DBAR_EXP_CC, "[01]12345678901231" }, + /* 85*/ { BARCODE_UPCA_CC, "1" }, + /* 86*/ { BARCODE_UPCE_CC, "1" }, + /* 87*/ { BARCODE_DBAR_STK_CC, "1" }, + /* 88*/ { BARCODE_DBAR_OMNSTK_CC, "1" }, + /* 89*/ { BARCODE_DBAR_EXPSTK_CC, "[01]12345678901231" }, + /* 90*/ { BARCODE_CHANNEL, "01" }, + /* 91*/ { BARCODE_CODEONE, "1" }, + /* 92*/ { BARCODE_GRIDMATRIX, "1" }, + /* 93*/ { BARCODE_UPNQR, "1" }, + /* 94*/ { BARCODE_ULTRA, "1" }, + /* 95*/ { BARCODE_RMQR, "1" }, + /* 96*/ { BARCODE_BC412, "1234567" }, +}; + +static void test_cap_stackable(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + const int data_size = ARRAY_SIZE(min_data); + const struct min_item *data = min_data; + int i, length, ret; + struct zint_symbol *symbol = NULL; + + const char *text; + + int prestacked_rows; + int stacked_rows; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + if (is_composite(data[i].symbology)) { + text = "[20]01"; + strcpy(symbol->primary, data[i].data); + } else { + text = data[i].data; + } + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + text, -1, debug); + + ret = ZBarcode_Encode(symbol, TCU(text), length); + assert_zero(ret, "i:%d ZBarcode_Encode prestacked ret %d != 0 %s\n", i, ret, symbol->errtxt); + + prestacked_rows = symbol->rows; + assert_nonzero(prestacked_rows, "i:%d prestacked_rows 0\n", i); + + symbol->eci = 0; + symbol->option_1 = -1; + symbol->option_2 = symbol->option_3 = 0; + + ret = ZBarcode_Encode(symbol, TCU(text), length); + assert_zero(ret, "i:%d ZBarcode_Encode stacked ret %d != 0 %s\n", i, ret, symbol->errtxt); + + stacked_rows = symbol->rows; + assert_nonzero(stacked_rows, "i:%d stacked_rows 0\n", i); + assert_nonzero(stacked_rows >= prestacked_rows, "i:%d stacked_rows %d < prestacked_rows %d\n", + i, stacked_rows, prestacked_rows); + + if (ZBarcode_Cap(symbol->symbology, ZINT_CAP_STACKABLE) & ZINT_CAP_STACKABLE) { + assert_nonzero(stacked_rows > prestacked_rows, "i:%d stacked_rows %d <= prestacked_rows %d\n", + i, stacked_rows, prestacked_rows); + } else { + assert_equal(stacked_rows, prestacked_rows, "i:%d stacked_rows %d != prestacked_rows %d\n", + i, stacked_rows, prestacked_rows); + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +static void test_bindable(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + const int data_size = ARRAY_SIZE(min_data); + const struct min_item *data = min_data; + int i, length, ret; + struct zint_symbol *symbol = NULL; + + int stackable; + int diff, nodiff; + int option_3; + + char prebind[32768]; + char bind[32768]; + + const char *text; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + /* This test can't differentiate these as always have bindings */ + nodiff = data[i].symbology == BARCODE_CODABLOCKF || data[i].symbology == BARCODE_CODE16K + || data[i].symbology == BARCODE_CODE49 || data[i].symbology == BARCODE_HIBC_BLOCKF; + + diff = ZBarcode_Cap(data[i].symbology, ZINT_CAP_STACKABLE | ZINT_CAP_BINDABLE); + option_3 = diff ? 3 : 0; + stackable = diff & ZINT_CAP_STACKABLE; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + if (is_composite(data[i].symbology)) { + text = "[20]01"; + strcpy(symbol->primary, data[i].data); + } else { + text = data[i].data; + } + strcpy(symbol->outfile, "mem.svg"); + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, option_3, BARCODE_MEMORY_FILE, + text, -1, debug); + + if (stackable) { + ret = ZBarcode_Encode(symbol, TCU(text), length); + assert_zero(ret, "i:%d ZBarcode_Encode prebind ret %d != 0 %s\n", i, ret, symbol->errtxt); + symbol->option_1 = -1; + symbol->option_2 = 0; + symbol->option_3 = option_3; + } + + ret = ZBarcode_Encode_and_Print(symbol, TCU(text), length, 0 /*rotate*/); + assert_zero(ret, "i:%d ZBarcode_Encode_and_Print prebind ret %d != 0 %s\n", i, ret, symbol->errtxt); + + assert_nonzero(symbol->memfile_size, "i:%d prebind memfile_size zero\n", i); + assert_nonzero(symbol->memfile_size + 1 < ARRAY_SIZE(prebind), + "i:%d prebind memfile_size + 1 %d >= ARRAY_SIZE(prebind) %d\n", + i, symbol->memfile_size, ARRAY_SIZE(prebind)); + + memcpy(prebind, symbol->memfile, symbol->memfile_size); + prebind[symbol->memfile_size] = '\0'; + + ZBarcode_Reset(symbol); + + if (is_composite(data[i].symbology)) { + text = "[20]01"; + strcpy(symbol->primary, data[i].data); + } else { + text = data[i].data; + } + strcpy(symbol->outfile, "mem.svg"); + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, option_3, BARCODE_BIND | BARCODE_MEMORY_FILE, + text, -1, debug); + + if (stackable) { + ret = ZBarcode_Encode(symbol, TCU(text), length); + assert_zero(ret, "i:%d ZBarcode_Encode bind ret %d != 0 %s\n", i, ret, symbol->errtxt); + symbol->option_1 = -1; + symbol->option_2 = 0; + symbol->option_3 = option_3; + } + + ret = ZBarcode_Encode_and_Print(symbol, TCU(text), length, 0 /*rotate*/); + assert_zero(ret, "i:%d ZBarcode_Encode_and_Print bind ret %d != 0 %s\n", i, ret, symbol->errtxt); + + assert_nonzero(symbol->memfile_size, "i:%d bind memfile_size zero\n", i); + assert_nonzero(symbol->memfile_size + 1 < ARRAY_SIZE(bind), + "i:%d bind memfile_size + 1 %d >= ARRAY_SIZE(bind) %d\n", + i, symbol->memfile_size, ARRAY_SIZE(bind)); + + memcpy(bind, symbol->memfile, symbol->memfile_size); + bind[symbol->memfile_size] = '\0'; + + if (diff && !nodiff) { + assert_nonzero(strlen(prebind) < strlen(bind), + "i:%d length prebind %d >= bind %d (prebind %s, bind %s)\n", + i, (int) strlen(prebind), (int) strlen(bind), prebind, bind); + assert_nonzero(strcmp(prebind, bind), "i:%d strcmp(%s, %s) == 0", i, prebind, bind); + } else { + assert_equal((int) strlen(prebind), (int) strlen(bind), + "i:%d length prebind %d >= bind %d (prebind %s, bind %s)\n", + i, (int) strlen(prebind), (int) strlen(bind), prebind, bind); + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + static void test_encode_file_empty(const testCtx *const p_ctx) { int ret; struct zint_symbol *symbol = NULL; @@ -999,7 +1330,8 @@ static void test_encode_file_empty(const testCtx *const p_ctx) { assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret); ret = ZBarcode_Encode_File(symbol, filename); - assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File empty ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); + assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File empty ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", + ret, symbol->errtxt); ret = testUtilRemove(filename); assert_zero(ret, "testUtilRemove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); @@ -1033,7 +1365,8 @@ static void test_encode_file_too_large(const testCtx *const p_ctx) { assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret); ret = ZBarcode_Encode_File(symbol, filename); - assert_equal(ret, ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_File too large ret %d != ZINT_ERROR_TOO_LONG (%s)\n", ret, symbol->errtxt); + assert_equal(ret, ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_File too large ret %d != ZINT_ERROR_TOO_LONG (%s)\n", + ret, symbol->errtxt); ret = testUtilRemove(filename); assert_zero(ret, "testUtilRemove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); @@ -1071,14 +1404,16 @@ static void test_encode_file_unreadable(const testCtx *const p_ctx) { /* Unreadable file */ fd = creat(filename, S_IWUSR); - assert_notequal(fd, -1, "Unreadable input file (%s) not created == -1 (%d: %s)\n", filename, errno, strerror(errno)); + assert_notequal(fd, -1, "Unreadable input file (%s) not created == -1 (%d: %s)\n", + filename, errno, strerror(errno)); ret = write(fd, buf, 1); assert_equal(ret, 1, "Unreadable write ret %d != 1\n", ret); ret = close(fd); assert_zero(ret, "Unreadable close(%s) != 0(%d: %s)\n", filename, errno, strerror(errno)); ret = ZBarcode_Encode_File(symbol, filename); - assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File unreadable ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); + assert_equal(ret, ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File unreadable ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); ret = testUtilRemove(filename); assert_zero(ret, "testUtilRemove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); @@ -1089,7 +1424,8 @@ static void test_encode_file_unreadable(const testCtx *const p_ctx) { #endif /* _WIN32 */ } -/* #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method */ +/* #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) + Note: unable to reproduce fread() error using this method */ static void test_encode_file_directory(const testCtx *const p_ctx) { int ret; struct zint_symbol *symbol = NULL; @@ -1252,7 +1588,8 @@ static void test_bad_args(const testCtx *const p_ctx) { assert_nonzero(ret >= 20901, "ZBarcode_Version() %d <= 20901\n", ret); assert_zero(ZBarcode_ValidID(0), "ZBarcode_ValidID(0) non-zero\n"); - assert_zero(ZBarcode_ValidID(10), "ZBarcode_ValidID(10) non-zero\n"); /* Note 10 remapped to BARCODE_EANX in ZBarcode_Encode() for tbarcode compat but not counted as valid */ + /* Note 10 remapped to BARCODE_EANX in ZBarcode_Encode() for tbarcode compat but not counted as valid */ + assert_zero(ZBarcode_ValidID(10), "ZBarcode_ValidID(10) non-zero\n"); uret = ZBarcode_Cap(0, ~0); assert_zero(uret, "ZBarcode_Cap(0, ~0) uret 0x%X != 0\n", uret); @@ -1260,112 +1597,225 @@ static void test_bad_args(const testCtx *const p_ctx) { assert_zero(uret, "ZBarcode_Cap(10, ~0) uret 0x%X != 0\n", uret); /* NULL symbol */ - assert_equal(ZBarcode_Encode(NULL, TCU(data), 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(NULL, data, 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_Segs(NULL, &seg, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(NULL, &seg, 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Print(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Print(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Buffer(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Buffer_Vector(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer_Vector(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_and_Print(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_Segs_and_Print(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Seg_and_Print(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_and_Buffer(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_and_Buffer_Vector(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_File(NULL, filename), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(NULL, filename) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_File_and_Print(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_equal(ZBarcode_Encode_File_and_Buffer(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode(NULL, TCU(data), 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode(NULL, data, 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_Segs(NULL, &seg, 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(NULL, &seg, 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Print(NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Print(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Buffer(NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Buffer(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Buffer_Vector(NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Buffer_Vector(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_and_Print(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Print(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_Segs_and_Print(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Seg_and_Print(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_and_Buffer(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_and_Buffer_Vector(NULL, TCU(data), 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer_Vector(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_File(NULL, filename), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File(NULL, filename) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_File_and_Print(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Print(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_equal(ZBarcode_Encode_File_and_Buffer(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Buffer(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); /* NULL data/segs/filename */ symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[0], symbol->errtxt), "ZBarcode_Encode(symbol, NULL, 1) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[0], symbol->errtxt), + "ZBarcode_Encode(symbol, NULL, 1) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[1], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, NULL, 1) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[1], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, NULL, 1) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Print(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[0], symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Print(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[0], symbol->errtxt), + "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[0], symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[0], symbol->errtxt), + "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[1], symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[1], symbol->errtxt), + "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", + expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[0], symbol->errtxt), "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[0], symbol->errtxt), + "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", + expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[1], symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", expected[0], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[1], symbol->errtxt), + "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) strcmp(%s, %s) != 0\n", + expected[0], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File(symbol, NULL), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, NULL) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[2], symbol->errtxt), "ZBarcode_Encode_File(symbol, NULL) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); + assert_equal(ZBarcode_Encode_File(symbol, NULL), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File(symbol, NULL) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[2], symbol->errtxt), + "ZBarcode_Encode_File(symbol, NULL) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Print(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[2], symbol->errtxt), "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); + assert_equal(ZBarcode_Encode_File_and_Print(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[2], symbol->errtxt), + "ZBarcode_Encode_File_and_Print(symbol, NULL, 0) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[2], symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); + assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[2], symbol->errtxt), + "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) strcmp(%s, %s) != 0\n", + expected[2], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[2], symbol->errtxt), "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) strcmp(%s, %s) != 0\n", expected[2], symbol->errtxt); + assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[2], symbol->errtxt), + "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) strcmp(%s, %s) != 0\n", + expected[2], symbol->errtxt); /* Empty data/segs/filename */ symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode(symbol, TCU(empty), 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode(symbol, TCU(empty), 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode(symbol, TCU(empty), 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode(symbol, TCU(empty), 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Print(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Print(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_and_Print(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", + expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Buffer(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Buffer(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_and_Buffer(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", + expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) strcmp(%s, %s) != 0\n", + expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_and_Buffer_Vector(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, TCU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_and_Buffer_Vector(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_and_Buffer_Vector(symbol, TCU(empty), 0, 0) strcmp(%s, %s) != 0\n", + expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[3], symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) strcmp(%s, %s) != 0\n", expected[3], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[3], symbol->errtxt), + "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) strcmp(%s, %s) != 0\n", + expected[3], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File(symbol, empty), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, empty) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", expected[4], symbol->errtxt, (int) strlen(expected[4])); + assert_equal(ZBarcode_Encode_File(symbol, empty), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File(symbol, empty) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), + "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", + expected[4], symbol->errtxt, (int) strlen(expected[4])); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Print(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", expected[4], symbol->errtxt, (int) strlen(expected[4])); + assert_equal(ZBarcode_Encode_File_and_Print(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Print(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), + "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", + expected[4], symbol->errtxt, (int) strlen(expected[4])); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", expected[4], symbol->errtxt, (int) strlen(expected[4])); + assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), + "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", + expected[4], symbol->errtxt, (int) strlen(expected[4])); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", expected[4], symbol->errtxt, (int) strlen(expected[4])); + assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strncmp(expected[4], symbol->errtxt, strlen(expected[4])), + "ZBarcode_Encode_File(symbol, empty) strncmp(%s, %s, %d) != 0\n", + expected[4], symbol->errtxt, (int) strlen(expected[4])); /* Bad seg_count */ symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[5], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) strcmp(%s, %s) != 0\n", expected[5], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[5], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) strcmp(%s, %s) != 0\n", + expected[5], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[6], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) strcmp(%s, %s) != 0\n", expected[6], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 0), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[6], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) strcmp(%s, %s) != 0\n", expected[6], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, -1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) != ZINT_ERROR_INVALID_DATA\n"); - assert_zero(strcmp(expected[6], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) strcmp(%s, %s) != 0\n", expected[6], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, -1), ZINT_ERROR_INVALID_DATA, + "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) != ZINT_ERROR_INVALID_DATA\n"); + assert_zero(strcmp(expected[6], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) strcmp(%s, %s) != 0\n", expected[6], symbol->errtxt); /* Data/seg too big */ symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode(symbol, TCU(empty), ZINT_MAX_DATA_LEN + 1), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) != ZINT_ERROR_TOO_LONG\n"); - assert_zero(strcmp(expected[7], symbol->errtxt), "ZBarcode_Encode(symbol, TCU(empty), ZINT_MAX_DATA_LEN + 1) strcmp(%s, %s) != 0\n", expected[7], symbol->errtxt); + assert_equal(ZBarcode_Encode(symbol, TCU(empty), ZINT_MAX_DATA_LEN + 1), ZINT_ERROR_TOO_LONG, + "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) != ZINT_ERROR_TOO_LONG\n"); + assert_zero(strcmp(expected[7], symbol->errtxt), + "ZBarcode_Encode(symbol, TCU(empty), ZINT_MAX_DATA_LEN + 1) strcmp(%s, %s) != 0\n", + expected[7], symbol->errtxt); symbol->errtxt[0] = '\0'; - assert_equal(ZBarcode_Encode_Segs(symbol, &seg_too_long, 1), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) != ZINT_ERROR_TOO_LONG\n"); - assert_zero(strcmp(expected[7], symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) strcmp(%s, %s) != 0\n", expected[7], symbol->errtxt); + assert_equal(ZBarcode_Encode_Segs(symbol, &seg_too_long, 1), ZINT_ERROR_TOO_LONG, + "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) != ZINT_ERROR_TOO_LONG\n"); + assert_zero(strcmp(expected[7], symbol->errtxt), + "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) strcmp(%s, %s) != 0\n", expected[7], symbol->errtxt); + + ZBarcode_Delete(symbol); + + testFinish(); +} + +static void test_stacking(const testCtx *const p_ctx) { + int ret; + struct zint_symbol *symbol = NULL; + const char *data = "1"; + const char *expected_error = "Error 770: Too many stacked symbols"; + int i; + + (void)p_ctx; + + testStartSymbol(p_ctx->func_name, &symbol); + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (i = 0; i < ARRAY_SIZE(symbol->row_height); i++) { + ret = ZBarcode_Encode(symbol, TCU(data), 0); + assert_zero(ret, "i:%d ZBarcode_Encode(%s) ret %d != 0 (%s)\n", i, data, ret, symbol->errtxt); + } + ret = ZBarcode_Encode(symbol, TCU(data), 0); + assert_equal(ret, ZINT_ERROR_TOO_LONG, "i:%d ZBarcode_Encode ret %d != ZINT_ERROR_TOO_LONG (%s)\n", + i, ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, expected_error), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, expected_error); ZBarcode_Delete(symbol); @@ -2468,6 +2918,8 @@ int main(int argc, char *argv[]) { { "test_escape_char_process_test", test_escape_char_process_test }, { "test_cap", test_cap }, { "test_cap_compliant_height", test_cap_compliant_height }, + { "test_cap_stackable", test_cap_stackable }, + { "test_bindable", test_bindable }, { "test_encode_file_empty", test_encode_file_empty }, { "test_encode_file_too_large", test_encode_file_too_large }, { "test_encode_file_unreadable", test_encode_file_unreadable }, @@ -2475,6 +2927,7 @@ int main(int argc, char *argv[]) { { "test_encode_file", test_encode_file }, { "test_encode_print_outfile_directory", test_encode_print_outfile_directory }, { "test_bad_args", test_bad_args }, + { "test_stacking", test_stacking }, { "test_valid_id", test_valid_id }, { "test_barcode_name", test_barcode_name }, { "test_error_tag", test_error_tag }, diff --git a/backend/tests/test_maxicode.c b/backend/tests/test_maxicode.c index 9dfb99ef..9944bc2e 100644 --- a/backend/tests/test_maxicode.c +++ b/backend/tests/test_maxicode.c @@ -2126,108 +2126,6 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 10 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - const char *primary; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_MAXICODE, UNICODE_MODE | ESCAPE_MODE, -1, -1, - "1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E", - "339010000840001", 0, 33, 30, "Mode 2" }, - /* 1*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, "MaxiCode (19 chars)", "", 0, 33, 30, "Mode 4 small" }, - /* 2*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, "ABCDabcdAabcABabcABCabcABCDaABCabABCabcABC\\d233a", "", 0, 33, 30, "Mode 4 medium" }, - /* 3*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, - "ABabcdeAabcdABCabcdABabc\\d192\\d192 \\d192\\d224\\d224\\d028\\d224\\d001\\d001\\d001\\d029\\d00112345678a123456789aABCDa\\d192\\d224\\d001\\d192\\d001\\d224\\d030\\d004", - "", 0, 33, 30, "Mode 4 latches" }, - /* 4*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, - "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", "", 0, 33, 30, "Mode 4 txt max" }, - /* 5*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, - "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", - "", 0, 33, 30, "Mode 4 num max" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0; - clock_t diff_create, diff_encode, diff_buffer; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - 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); - strcpy(symbol->primary, data[i].primary); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - #if 0 - 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); - #endif - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -2238,7 +2136,6 @@ int main(int argc, char *argv[]) { { "test_rt", test_rt }, { "test_rt_segs", test_rt_segs }, { "test_fuzz", test_fuzz }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c index c55ee8a6..7f07e31a 100644 --- a/backend/tests/test_output.c +++ b/backend/tests/test_output.c @@ -209,7 +209,8 @@ INTERNAL int out_quiet_zones_test(const struct zint_symbol *symbol, const int hi static void test_quiet_zones(const testCtx *const p_ctx) { int i, ret; - struct zint_symbol symbol = {0}; + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; int hide_text = 0; int comp_xoffset = 0; float left, right, top, bottom; @@ -220,9 +221,9 @@ static void test_quiet_zones(const testCtx *const p_ctx) { if (!ZBarcode_ValidID(i)) continue; if (testContinue(p_ctx, i)) continue; - symbol.symbology = i; - symbol.output_options = BARCODE_QUIET_ZONES; - ret = out_quiet_zones_test(&symbol, hide_text, comp_xoffset, &left, &right, &top, &bottom); + symbol->symbology = i; + symbol->output_options = BARCODE_QUIET_ZONES; + ret = out_quiet_zones_test(symbol, hide_text, comp_xoffset, &left, &right, &top, &bottom); if (i != BARCODE_FLAT && i != BARCODE_BC412) { /* Only two which aren't marked as done */ assert_nonzero(ret, "i:%d %s not done\n", i, testUtilBarcodeName(i)); } diff --git a/backend/tests/test_pdf417.c b/backend/tests/test_pdf417.c index 36456922..ca3a3c8b 100644 --- a/backend/tests/test_pdf417.c +++ b/backend/tests/test_pdf417.c @@ -78,34 +78,48 @@ static void test_large(const testCtx *const p_ctx) { if (data[i].length != -1) { testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); } else { strcpy(data_buf, data[i].pattern); } - length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, symbol->errtxt); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, symbol->errtxt); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); /* FAST_MODE */ - length = testUtilSetSymbol(symbol, data[i].symbology, FAST_MODE, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug); + ZBarcode_Clear(symbol); + length = testUtilSetSymbol(symbol, data[i].symbology, FAST_MODE /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, symbol->errtxt); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, symbol->errtxt); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); ZBarcode_Delete(symbol); } @@ -193,7 +207,7 @@ static void test_options(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - struct zint_symbol previous_symbol; + struct zint_symbol *previous_symbol = NULL; testStartSymbol(p_ctx->func_name, &symbol); @@ -233,11 +247,10 @@ static void test_options(const testCtx *const p_ctx) { i, symbol->option_3, data[i].expected_option_3); if (p_ctx->index == -1 && data[i].compare_previous != -1) { - ret = testUtilSymbolCmp(symbol, &previous_symbol); + ret = testUtilSymbolCmp(symbol, previous_symbol); assert_equal(!ret, !data[i].compare_previous, "i:%d testUtilSymbolCmp !ret %d != %d\n", i, ret, data[i].compare_previous); } - memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); if (data[i].ret_vector != -1) { ret = ZBarcode_Buffer_Vector(symbol, 0); @@ -245,8 +258,10 @@ static void test_options(const testCtx *const p_ctx) { i, ret, data[i].ret_vector); } - ZBarcode_Delete(symbol); + ZBarcode_Delete(previous_symbol); + previous_symbol = symbol; } + ZBarcode_Delete(previous_symbol); testFinish(); } @@ -291,10 +306,13 @@ static void test_reader_init(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", @@ -303,10 +321,13 @@ static void test_reader_init(const testCtx *const p_ctx) { testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -465,55 +486,75 @@ static void test_input(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, + data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %s, %d, %d, %d, \"%s\", %d, \"%s\" },\n", - i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, + i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci, + data[i].option_1, data[i].option_2, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->eci, symbol->rows, symbol->width, symbol->errtxt, data[i].bwipp_cmp, data[i].comment); } else { if (ret < ZINT_ERROR) { - assert_equal(symbol->eci, data[i].expected_eci, "i:%d symbol->eci %d != %d (%s)\n", i, symbol->eci, data[i].expected_eci, data[i].data); - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->eci, data[i].expected_eci, "i:%d symbol->eci %d != %d (%s)\n", + i, symbol->eci, data[i].expected_eci, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { if (ret == 0 && p_ctx->index == -1) { if (i && (data[i - 1].input_mode & FAST_MODE) && !(data[i].input_mode & FAST_MODE) && strcmp(data[i - 1].data, data[i].data) == 0) { int num_cwds; - assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", i, symbol->errtxt); - assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", i, last_fast_num_cwds, num_cwds); - if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { + assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", + i, symbol->errtxt); + assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", + i, last_fast_num_cwds, num_cwds); + if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) + && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { printf("i:%d diff %d\n", i, num_cwds - last_fast_num_cwds); } } if (data[i].input_mode & FAST_MODE) { - assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); + assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, + "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); } } if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + + } } else { char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -3973,10 +4014,13 @@ static void test_encode(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, %d, %d, %d, \"%s\", %s, %d, %d, %d, %d, \"%s\",\n", @@ -3992,37 +4036,51 @@ static void test_encode(const testCtx *const p_ctx) { testUtilEscape(data[i].data, length, escaped, sizeof(escaped)); - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, escaped); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, escaped); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, escaped); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, escaped); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, escaped); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, escaped); if (ret == 0 && p_ctx->index == -1) { if (i && (data[i - 1].input_mode & FAST_MODE) && !(data[i].input_mode & FAST_MODE) && strcmp(data[i - 1].data, data[i].data) == 0) { int num_cwds; - assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", i, symbol->errtxt); - assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", i, last_fast_num_cwds, num_cwds); - if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { + assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", + i, symbol->errtxt); + assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", + i, last_fast_num_cwds, num_cwds); + if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) + && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { printf("i:%d diff %d\n", i, num_cwds - last_fast_num_cwds); } } if (data[i].input_mode & FAST_MODE) { - assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); + assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, + "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); } } - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -4719,11 +4777,13 @@ static void test_encode_segs(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, NULL, 0, debug); + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + NULL, 0, debug); for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; @@ -4735,9 +4795,12 @@ static void test_encode_segs(const testCtx *const p_ctx) { i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, data[i].option_3, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, - testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, - testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, - testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, + testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), + data[i].segs[0].length, data[i].segs[0].eci, + testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), + data[i].segs[1].length, data[i].segs[1].eci, + testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), + data[i].segs[2].length, data[i].segs[2].eci, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); if (data[i].ret < ZINT_ERROR) { testUtilModulesPrint(symbol, " ", "\n"); @@ -4749,8 +4812,10 @@ static void test_encode_segs(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row); @@ -4758,30 +4823,42 @@ static void test_encode_segs(const testCtx *const p_ctx) { if (data[i].ret == 0 && p_ctx->index == -1) { if (i && (data[i - 1].input_mode & FAST_MODE) && !(data[i].input_mode & FAST_MODE)) { int num_cwds; - assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", i, symbol->errtxt); - assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", i, last_fast_num_cwds, num_cwds); - if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { + assert_equal(sscanf(symbol->errtxt, "(%d)", &num_cwds), 1, "i:%d num_cwds sscanf != 1 (%s)\n", + i, symbol->errtxt); + assert_nonzero(last_fast_num_cwds >= num_cwds, "i:%d last_fast_num_cwds %d < num_cwds %d\n", + i, last_fast_num_cwds, num_cwds); + if (num_cwds < last_fast_num_cwds && (debug & ZINT_DEBUG_TEST_PRINT) + && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { printf("i:%d diff %d\n", i, num_cwds - last_fast_num_cwds); } } if (data[i].input_mode & FAST_MODE) { - assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); + assert_equal(sscanf(symbol->errtxt, "(%d)", &last_fast_num_cwds), 1, + "i:%d last_fast sscanf != 1 (%s)\n", i, symbol->errtxt); } } - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); - assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); + assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } - if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) { + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, + data[i].segs[0].length, debug)) { if ((data[i].input_mode & 0x07) == DATA_MODE) { if (debug & ZINT_DEBUG_TEST_PRINT) { printf("i:%d %s multiple segments in DATA_MODE not currently supported for ZXing-C++ testing\n", @@ -5826,25 +5903,34 @@ static void test_fuzz(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - 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, data[i].length, debug); + 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, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -6018,17 +6104,21 @@ static void test_numbprocess(const testCtx *const p_ctx) { length = (int) ustrlen(data[i].chaine); mclength = 0; pdf_numbprocess_test(chainemc, &mclength, data[i].chaine, 0, length); - assert_nonzero(mclength < ARRAY_SIZE(chainemc), "i:%d mclength %d >= ARRAY_SIZE(chainemc) %d\n", i, mclength, ARRAY_SIZE(chainemc)); + assert_nonzero(mclength < ARRAY_SIZE(chainemc), "i:%d mclength %d >= ARRAY_SIZE(chainemc) %d\n", + i, mclength, ARRAY_SIZE(chainemc)); #if 0 for (j = 0; j < mclength; j++) { printf(" %d", chainemc[j]); } printf("\n"); #endif - assert_equal(mclength, data[i].expected_len, "i:%d mclength %d != expected_len %d\n", i, mclength, data[i].expected_len); + assert_equal(mclength, data[i].expected_len, "i:%d mclength %d != expected_len %d\n", + i, mclength, data[i].expected_len); for (j = 0; j < mclength; j++) { - assert_equal(chainemc[j], data[i].expected[j], "i:%d chainemc[%d] %d != %d\n", i, j, chainemc[j], data[i].expected[j]); + assert_equal(chainemc[j], data[i].expected[j], "i:%d chainemc[%d] %d != %d\n", + i, j, chainemc[j], data[i].expected[j]); } if (length < 20) { char buf1[64], buf2[64]; - assert_zero(annex_d_decode_dump(chainemc, mclength, data[i].chaine, length, buf1, buf2), "i:%d annex_d_decode_dump() fail\n", i); + assert_zero(annex_d_decode_dump(chainemc, mclength, data[i].chaine, length, buf1, buf2), + "i:%d annex_d_decode_dump() fail\n", i); assert_zero(strcmp(buf1, buf2), "i:%d, strcmp(%s, %s) != 0\n", i, buf1, buf2); } } @@ -6036,208 +6126,6 @@ static void test_numbprocess(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_PDF417, -1, -1, -1, "1234567890", 0, 7, 103, "10 numerics" }, - /* 1*/ { BARCODE_PDF417, -1, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" - "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" - "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" - "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" - "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" - "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", - 0, 43, 290, "960 chars, text/numeric" }, - /* 2*/ { 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" }, - /* 3*/ { BARCODE_PDF417, -1, -1, -1, - "BP2D+1.00+0005+FLE ESC BV+1.00+3.60*BX2D+1.00+0001+Casual shoes & apparel+90044030118100801265*D_2D+1.02+31351440315981+C910332+02032018+KXXXX CXXXX+UNIT 4 HXXX" - "XXXXX BUSINESS PARK++ST ALBANS+ST ALBANS++AL2 3TA+0001+000001+001+00000000+00++N+N+N+0000++++++N+++N*DS2D+1.01+0001+0001+90044030118100801265+++++07852389322+" - "+E*F_2D+1.00+0005*", - 0, 26, 222, "338 chars, text/numeric/byte" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - printf("FAST_MODE\n"); - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - int input_mode = data[i].input_mode == -1 ? FAST_MODE : (data[i].input_mode | FAST_MODE); - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, 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, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } - - printf("OPTIMIZED\n"); - total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -6251,7 +6139,6 @@ int main(int argc, char *argv[]) { { "test_rt_segs", test_rt_segs }, { "test_fuzz", test_fuzz }, { "test_numbprocess", test_numbprocess }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_perf.c b/backend/tests/test_perf.c new file mode 100644 index 00000000..0f1ea995 --- /dev/null +++ b/backend/tests/test_perf.c @@ -0,0 +1,718 @@ +/* These are not real tests, just performance indicators */ +/* + libzint - the open source barcode library + Copyright (C) 2025 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include "testcommon.h" + +#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) + +struct perf_item { + int symbology; + int input_mode; + int option_1; + int option_2; + int option_3; + const char *data; + const char *composite_primary; + int ret; + + int expected_rows; + int expected_width; + const char *comment; +}; + +static void test_perf(const testCtx *const p_ctx, const int default_iterations, const struct perf_item *data, + const int data_size) { + int debug = p_ctx->debug; + + int i, length, ret; + struct zint_symbol *symbol = NULL; + + clock_t start; + clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; + clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; + int comment_max = 0; + + const int iterations = p_ctx->arg ? p_ctx->arg : default_iterations; /* Use "-a N" to set iterations */ + + const char *text; + + if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ + return; + } + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); + } + + printf(" Iterations %d\n", iterations); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; + + for (j = 0; j < iterations; j++) { + start = clock(); + symbol = ZBarcode_Create(); + diff_create += clock() - start; + assert_nonnull(symbol, "Symbol not created\n"); + + if (strlen(data[i].composite_primary)) { + if (is_composite(data[i].symbology)) { + text = data[i].composite_primary; + assert_nonzero((int) strlen(data[i].data) < ARRAY_SIZE(symbol->primary), + "i:%d composite length %d >= %d\n", + i, (int) strlen(data[i].data), ARRAY_SIZE(symbol->primary)); + strcpy(symbol->primary, data[i].data); + } else { + text = data[i].data; + assert_nonzero((int) strlen(data[i].composite_primary) < ARRAY_SIZE(symbol->primary), + "i:%d primary length %d >= %d\n", + i, (int) strlen(data[i].composite_primary), ARRAY_SIZE(symbol->primary)); + strcpy(symbol->primary, data[i].composite_primary); + } + } else { + text = data[i].data; + } + + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + text, -1, debug); + + start = clock(); + ret = ZBarcode_Encode(symbol, TCU(text), 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); + + symbol->output_options |= OUT_BUFFER_INTERMEDIATE; + start = clock(); + ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); + diff_buf_inter += clock() - start; + assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", + i, ret, symbol->errtxt); + symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ + + start = clock(); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + diff_print += clock() - start; + assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ZBarcode_Delete(symbol); + } + + printf(" %*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", + comment_max, data[i].comment, + TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), + TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); + + total_create += diff_create; + total_encode += diff_encode; + total_buffer += diff_buffer; + total_buf_inter += diff_buf_inter; + total_print += diff_print; + } + if (p_ctx->index == -1) { + printf(" %*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", + comment_max, "totals", + TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), + TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); + } + + testFinish(); +} + +static void test_2of5(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_C25INTER, -1, -1, -1, -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "", 0, 1, 819, "C25INTER 90" }, + /* 1*/ { BARCODE_C25INTER, -1, -1, -1, -1, "1234567890", "", 0, 1, 99, "C25INTER 10" }, + /* 2*/ { BARCODE_C25STANDARD, -1, -1, -1, -1, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "", 0, 1, 817, "C25STANDARD 80" }, + /* 3*/ { BARCODE_C25STANDARD, -1, -1, -1, -1, "1234567890", "", 0, 1, 117, "C25STANDARD 10" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_aztec(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_AZTEC, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "", 0, 49, 49, "286 chars, 8-bit words, upper" }, + /* 1*/ { BARCODE_AZTEC, -1, -1, -1, -1, + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", + "", 0, 79, 79, "900 chars, 10-bit words, numeric" }, + /* 2*/ { BARCODE_AZTEC, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377", + "", 0, 91, 91, "980 chars, 10-bit words, mixed" }, + /* 3*/ { BARCODE_AZTEC, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ~~~~~~~~~~~~~~~~~~~~~~~~~ ?????????????????????????? 12345678901234567890123456 \377\377\377\377\377\377", + "", 0, 113, 113, "1540 chars, 12-bit words, mixed" }, + /* 4*/ { BARCODE_AZRUNE, -1, -1, -1, -1, + "255", + "", 0, 11, 11, "3 chars, AZRUNE" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 1 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_code11(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_CODE11, -1, -1, -1, -1, "1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-1234567890-", "", 0, 1, 966, "CODE11 121" }, + /* 1*/ { BARCODE_CODE11, -1, -1, -1, -1, "1234567890-", "", 0, 1, 116, "CODE11 5" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_code128(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_CODE128, -1, -1, -1, -1, "123456ABCD123456ABCD123456ABCD123456ABCD123456ABCD123456ABCD", "", 0, 1, 618, "CODE128 60" }, + /* 1*/ { BARCODE_CODE128, -1, -1, -1, -1, "123456ABCD", "", 0, 1, 123, "CODE128 10" }, + /* 2*/ { BARCODE_GS1_128, -1, -1, -1, -1, "[01]09501101530003", "", 0, 1, 134, "GS1_128 (01)" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_composite(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_EANX_CC, -1, 1, -1, -1, "123456789012", + "[91]123456789012345678901234567890123456789012345678901234", + 0, 11, 99, "58 chars CC-A" }, + /* 1*/ { BARCODE_UPCA_CC, -1, 2, -1, -1, "12345678901", + "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[94]12345678901234567890123456789012345678901234567890", + 0, 48, 99, "336 chars CC-B" }, + /* 2*/ { BARCODE_GS1_128_CC, -1, 3, -1, -1, "[01]12345678901231", + "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", + 0, 32, 205, "564 chars CC-C" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 1 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_dmatrix(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" + "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" + "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" + "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" + "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", + "", 0, 96, 96, "960 chars, text/numeric" }, + /* 1*/ { BARCODE_DATAMATRIX, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" + "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" + "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" + "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" + "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", + "", 0, 96, 96, "960 chars, text/numeric" }, + /* 2*/ { BARCODE_DATAMATRIX, DATA_MODE | FAST_MODE, -1, -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, 120, 120, "960 chars, byte" }, + /* 3*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, -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, 120, 120, "960 chars, byte" }, + /* 4*/ { BARCODE_DATAMATRIX, FAST_MODE, -1, -1, -1, "https://example.com/01/09506000134369", "", 0, 22, 22, "37 chars, text/numeric" }, + /* 5*/ { BARCODE_DATAMATRIX, -1, -1, -1, -1, "https://example.com/01/09506000134369", "", 0, 22, 22, "37 chars, text/numeric" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_dotcode(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_DOTCODE, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" + "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" + "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" + "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" + "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", + "", 0, 124, 185, "960 chars, text/numeric" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 1 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_gridmtx(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, -1, -1, -1, + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738", + "", 0, 66, 66, "97 chars, mixed modes" }, + /* 1*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, -1, -1, -1, + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738" + "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738 AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 82512738", + "", 0, 162, 162, "970 chars, mixed modes" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 1 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_hanxin(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, -1, + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", + "", ZINT_WARN_NONCOMPLIANT, 43, 43, "98 chars, Region One and Text" }, + /* 1*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, -1, + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", + "", ZINT_WARN_NONCOMPLIANT, 121, 121, "980 chars, Region One and Text" }, + /* 2*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, -1, + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" + "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", + "", ZINT_WARN_NONCOMPLIANT, 147, 147, "1470 chars, Region One and Text" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 1 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_maxicode(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_MAXICODE, UNICODE_MODE | ESCAPE_MODE, -1, -1, -1, + "1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E", + "339010000840001", 0, 33, 30, "Mode 2" }, + /* 1*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, -1, "MaxiCode (19 chars)", "", 0, 33, 30, "Mode 4 small" }, + /* 2*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, -1, "ABCDabcdAabcABabcABCabcABCDaABCabABCabcABC\\d233a", "", 0, 33, 30, "Mode 4 medium" }, + /* 3*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, -1, + "ABabcdeAabcdABCabcdABabc\\d192\\d192 \\d192\\d224\\d224\\d028\\d224\\d001\\d001\\d001\\d029\\d00112345678a123456789aABCDa\\d192\\d224\\d001\\d192\\d001\\d224\\d030\\d004", + "", 0, 33, 30, "Mode 4 latches" }, + /* 4*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, -1, + "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", "", 0, 33, 30, "Mode 4 txt max" }, + /* 5*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, -1, + "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", + "", 0, 33, 30, "Mode 4 num max" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 10 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_pdf417(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_PDF417, -1, -1, -1, -1, "1234567890", "", 0, 7, 103, "10 numerics" }, + /* 1*/ { BARCODE_PDF417, -1, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz&,:#-.$/+%*=^ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ;<>@[]_`~!||()?{}'123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJK" + "LMNOPQRSTUVWXYZ12345678912345678912345678912345678900001234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFG" + "HIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567" + "890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcde" + "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO", + "", 0, 43, 290, "960 chars, text/numeric" }, + /* 2*/ { BARCODE_PDF417, DATA_MODE, -1, -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" }, + /* 3*/ { BARCODE_PDF417, -1, -1, -1, -1, + "BP2D+1.00+0005+FLE ESC BV+1.00+3.60*BX2D+1.00+0001+Casual shoes & apparel+90044030118100801265*D_2D+1.02+31351440315981+C910332+02032018+KXXXX CXXXX+UNIT 4 HXXX" + "XXXXX BUSINESS PARK++ST ALBANS+ST ALBANS++AL2 3TA+0001+000001+001+00000000+00++N+N+N+0000++++++N+++N*DS2D+1.01+0001+0001+90044030118100801265+++++07852389322+" + "+E*F_2D+1.00+0005*", + "", 0, 26, 222, "338 chars, text/numeric/byte" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_plessey(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_PLESSEY, -1, -1, -1, -1, "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1", "", 0, 1, 1107, "PLESSEY 65" }, + /* 1*/ { BARCODE_PLESSEY, -1, -1, -1, -1, "123456ABCD", "", 0, 1, 227, "PLESSEY 10" }, + /* 2*/ { BARCODE_MSI_PLESSEY, -1, -1, -1, -1, "12345678901234567890123456789012345678901234567890123456789012345", "", 0, 1, 787, "MSI_PLESSEY 65" }, + /* 3*/ { BARCODE_MSI_PLESSEY, -1, -1, -1, -1, "1234567890", "", 0, 1, 127, "MSI_PLESSEY 10" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_postal(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_POSTNET, -1, -1, -1, -1, "12345678901", "", 0, 2, 123, "POSTNET 11" }, + /* 1*/ { BARCODE_PLANET, -1, -1, -1, -1, "1234567890123", "", 0, 2, 143, "PLANET 13" }, + /* 2*/ { BARCODE_KOREAPOST, -1, -1, -1, -1, "123456", "", 0, 1, 167, "KOREAPOST 6" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 10 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_qr(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "12345678901234", "", 0, 21, 21, "14 chars, Numeric mode" }, + /* 1*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "ABC 123 ABC 123 ABCD", "", 0, 21, 21, "20 chars, Alphanumeric" }, + /* 2*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "ABCde fG H 123456 IJKlmn, 1234567890 opQ Rst uvwxyz. 1234", "", 0, 29, 29, "57 chars, Alphanumeric" }, + /* 3*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 37, 37, "107 chars, Mixed modes" }, + /* 4*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 53, 53, "214 chars, Mixed modes" }, + /* 5*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 73, 73, "428 chars, Mixed modes" }, + /* 6*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 105, 105, "963 chars, Mixed modes" }, + /* 7*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 133, 133, "1498 chars, Mixed modes" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_qr_fast(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, "12345678901234", "", 0, 21, 21, "14 chars, Numeric mode" }, + /* 1*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, "ABC 123 ABC 123 ABCD", "", 0, 21, 21, "20 chars, Alphanumeric" }, + /* 2*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, "ABCde fG H 123456 IJKlmn, 1234567890 opQ Rst uvwxyz. 1234", "", 0, 29, 29, "57 chars, Alphanumeric" }, + /* 3*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 37, 37, "107 chars, Mixed modes" }, + /* 4*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 53, 53, "214 chars, Mixed modes" }, + /* 5*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 73, 73, "428 chars, Mixed modes" }, + /* 6*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 105, 105, "963 chars, Mixed modes" }, + /* 7*/ { BARCODE_QRCODE, UNICODE_MODE | FAST_MODE, -1, -1, -1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", + "", ZINT_WARN_NONCOMPLIANT, 133, 133, "1498 chars, Mixed modes" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_microqr(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 1, -1, "12345", "", 0, 11, 11, "Max 5 numbers, M1" }, + /* 1*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 2, -1, "1234567890", "", 0, 13, 13, "Max 10 numbers, M2-L" }, + /* 2*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 3, -1, "123456789012345", "", 0, 15, 15, "Max 15 numbers, M3-L" }, + /* 3*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 4, -1, "12345678901234567890123456789012345", "", 0, 17, 17, "Max 35 numbers, M4-L" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 5 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +static void test_upcean(const testCtx *const p_ctx) { + + static const struct perf_item data[] = { + /* 0*/ { BARCODE_EANX, -1, -1, -1, -1, "123456789012+12345", "", 0, 1, 149, "EAN-13 add-on 5" }, + /* 1*/ { BARCODE_EANX, -1, -1, -1, -1, "123456789012", "", 0, 1, 95, "EAN-13 no add-on" }, + /* 2*/ { BARCODE_UPCA, -1, -1, -1, -1, "12345678901+12345", "", 0, 1, 151, "UPC-A add-on 5" }, + /* 3*/ { BARCODE_UPCA, -1, -1, -1, -1, "12345678901", "", 0, 1, 95, "UPC-A no add-on" }, + /* 4*/ { BARCODE_EANX, -1, -1, -1, -1, "1234567+12345", "", 0, 1, 121, "EAN-8 add-on 5" }, + /* 5*/ { BARCODE_EANX, -1, -1, -1, -1, "1234567", "", 0, 1, 67, "EAN-8 no add-on" }, + /* 6*/ { BARCODE_UPCE, -1, -1, -1, -1, "1234567+12", "", 0, 1, 78, "UPC-E add-on 2" }, + /* 7*/ { BARCODE_UPCE, -1, -1, -1, -1, "1234567", "", 0, 1, 51, "UPC-E no add-on" }, + /* 8*/ { BARCODE_EANX, -1, -1, -1, -1, "12345", "", 0, 1, 47, "EAN-5" }, + /* 9*/ { BARCODE_EANX, -1, -1, -1, -1, "12", "", 0, 1, 20, "EAN-2" }, + }; + const int data_size = ARRAY_SIZE(data); + const int default_iterations = 10 * 1000; + + test_perf(p_ctx, default_iterations, data, data_size); +} + +int main(int argc, char *argv[]) { + + testFunction funcs[] = { /* name, func */ + { "test_2of5", test_2of5 }, + { "test_aztec", test_aztec }, + { "test_code11", test_code11 }, + { "test_code128", test_code128 }, + { "test_composite", test_composite }, + { "test_dmatrix", test_dmatrix }, + { "test_dotcode", test_dotcode }, + { "test_gridmtx", test_gridmtx }, + { "test_hanxin", test_hanxin }, + { "test_maxicode", test_maxicode }, + { "test_pdf417", test_pdf417 }, + { "test_plessey", test_plessey }, + { "test_postal", test_postal }, + { "test_qr", test_qr }, + { "test_qr_fast", test_qr_fast }, + { "test_microqr", test_microqr }, + { "test_upcean", test_upcean }, + }; + + testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); + + testReport(); + + return 0; +} + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_plessey.c b/backend/tests/test_plessey.c index 668a490b..723beb03 100644 --- a/backend/tests/test_plessey.c +++ b/backend/tests/test_plessey.c @@ -398,108 +398,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_PLESSEY, -1, "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1", 0, 1, 1107, "PLESSEY 65" }, - /* 1*/ { BARCODE_PLESSEY, -1, "123456ABCD", 0, 1, 227, "PLESSEY 10" }, - /* 2*/ { BARCODE_MSI_PLESSEY, -1, "12345678901234567890123456789012345678901234567890123456789012345", 0, 1, 787, "MSI_PLESSEY 65" }, - /* 3*/ { BARCODE_MSI_PLESSEY, -1, "1234567890", 0, 1, 127, "MSI_PLESSEY 10" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -507,7 +405,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_postal.c b/backend/tests/test_postal.c index f681c4c6..5b8d4f24 100644 --- a/backend/tests/test_postal.c +++ b/backend/tests/test_postal.c @@ -616,107 +616,6 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 10 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) ((arg) * 1000.0 / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_POSTNET, -1, "12345678901", 0, 2, 123, "POSTNET 11" }, - /* 1*/ { BARCODE_PLANET, -1, "1234567890123", 0, 2, 143, "PLANET 13" }, - /* 2*/ { BARCODE_KOREAPOST, -1, "123456", 0, 1, 167, "KOREAPOST 6" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -726,7 +625,6 @@ int main(int argc, char *argv[]) { { "test_hrt", test_hrt }, { "test_input", test_input }, { "test_encode", test_encode }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_qr.c b/backend/tests/test_qr.c index a1b7fb59..a9a3afa1 100644 --- a/backend/tests/test_qr.c +++ b/backend/tests/test_qr.c @@ -90,35 +90,56 @@ static void test_qr_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_QRCODE, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3 | FAST_MODE, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_QRCODE, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - symbol->input_mode |= FAST_MODE; + ZBarcode_Clear(symbol); + length = testUtilSetSymbol(symbol, BARCODE_QRCODE, FAST_MODE /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + + 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->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { char modules_dump[177 * 177 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data_buf, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data_buf, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -127,9 +148,12 @@ static void test_qr_large(const testCtx *const p_ctx) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data_buf, length, debug)) { int cmp_len, ret_len; char modules_dump[177 * 177 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data_buf, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data_buf, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data_buf, length, NULL /*primary*/, escaped, &ret_len); @@ -224,7 +248,7 @@ static void test_qr_options(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - struct zint_symbol previous_symbol; + struct zint_symbol *previous_symbol = NULL; char option_3_buf[64]; @@ -245,13 +269,15 @@ static void test_qr_options(const testCtx *const p_ctx) { } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret_encode, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (p_ctx->index == -1 && data[i].compare_previous != -1) { - ret = testUtilSymbolCmp(symbol, &previous_symbol); - assert_equal(!ret, !data[i].compare_previous, "i:%d testUtilSymbolCmp !ret %d != %d\n", i, ret, data[i].compare_previous); + ret = testUtilSymbolCmp(symbol, previous_symbol); + assert_equal(!ret, !data[i].compare_previous, "i:%d testUtilSymbolCmp !ret %d != %d\n", + i, ret, data[i].compare_previous); } - memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); if (data[i].ret_vector != -1) { ret = ZBarcode_Buffer_Vector(symbol, 0); @@ -271,8 +297,10 @@ static void test_qr_options(const testCtx *const p_ctx) { i, symbol->option_3, option_3_buf, data[i].expected_option_3, testUtilOption3Name(BARCODE_QRCODE, data[i].expected_option_3)); - ZBarcode_Delete(symbol); + ZBarcode_Delete(previous_symbol); + previous_symbol = symbol; } + ZBarcode_Delete(previous_symbol); testFinish(); } @@ -713,10 +741,13 @@ static void test_qr_gs1(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_QRCODE, data[i].input_mode, -1 /*eci*/, data[i].option_1, -1, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_QRCODE, data[i].input_mode, -1 /*eci*/, + data[i].option_1, -1 /*option_2*/, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %s, \"%s\", %s, \"%s\", %d, \"%s\" },\n", @@ -725,16 +756,23 @@ static void test_qr_gs1(const testCtx *const p_ctx) { testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[177 * 177 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, -1, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, -1, data[i].option_3, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -852,7 +890,8 @@ static void test_qr_optimize(const testCtx *const p_ctx) { assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, data[i].option_3 | ZINT_FULL_MULTIBYTE, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, data[i].option_3 | ZINT_FULL_MULTIBYTE, + debug)) { if (!data[i].bwipp_cmp) { if (debug & ZINT_DEBUG_TEST_PRINT) { printf("i:%d %s not BWIPP compatible (%s)\n", @@ -4382,7 +4421,8 @@ static void test_qr_encode(const testCtx *const p_ctx) { } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %d, %s, %d, %d, %d, %d, \"%s\",\n", @@ -4407,7 +4447,8 @@ static void test_qr_encode(const testCtx *const p_ctx) { assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { if (debug & ZINT_DEBUG_TEST_PRINT) { printf("i:%d %s not BWIPP compatible (%s)\n", @@ -4722,7 +4763,8 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; @@ -4734,31 +4776,43 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].symbology, data[i].option_3), data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, - testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, - testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, - testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, + testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), + data[i].segs[0].length, data[i].segs[0].eci, + testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), + data[i].segs[1].length, data[i].segs[1].eci, + testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), + data[i].segs[2].length, data[i].segs[2].eci, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); } else { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); - assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); + assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp) { @@ -4772,14 +4826,17 @@ static void test_qr_encode_segs(const testCtx *const p_ctx) { if (testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length, debug)) { int cmp_len, ret_len; char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count, NULL /*primary*/, escaped, &ret_len); - assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + assert_zero(ret, + "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); } @@ -4983,182 +5040,6 @@ static void test_qr_rt_segs(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 5 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_qr_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, "12345678901234", 0, 21, 21, "14 chars, Numeric mode" }, - /* 1*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, "ABC 123 ABC 123 ABCD", 0, 21, 21, "20 chars, Alphanumeric" }, - /* 2*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, "ABCde fG H 123456 IJKlmn, 1234567890 opQ Rst uvwxyz. 1234", 0, 29, 29, "57 chars, Alphanumeric" }, - /* 3*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", - ZINT_WARN_NONCOMPLIANT, 37, 37, "107 chars, Mixed modes" }, - /* 4*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", - ZINT_WARN_NONCOMPLIANT, 53, 53, "214 chars, Mixed modes" }, - /* 5*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", - ZINT_WARN_NONCOMPLIANT, 73, 73, "428 chars, Mixed modes" }, - /* 6*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", - ZINT_WARN_NONCOMPLIANT, 105, 105, "963 chars, Mixed modes" }, - /* 7*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 12345678901234567890123456 点点点点点点点点点点点点点点点点点点点点点点点点点点", - ZINT_WARN_NONCOMPLIANT, 133, 133, "1498 chars, Mixed modes" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0; - clock_t diff_create, diff_encode, diff_buffer; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - printf("FAST_MODE\n"); - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - int input_mode = data[i].input_mode == -1 ? FAST_MODE : (data[i].input_mode | FAST_MODE); - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, 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, TCU(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); - - #if 0 - 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); - #endif - - 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: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - } - if (p_ctx->index != -1) { - printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_create)); - } - - printf("OPTIMIZED\n"); - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - } - if (p_ctx->index != -1) { - printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_create)); - } -} - static void test_microqr_options(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -5250,7 +5131,7 @@ static void test_microqr_options(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - struct zint_symbol previous_symbol; + struct zint_symbol *previous_symbol = NULL; char option_3_buf[64]; @@ -5268,31 +5149,39 @@ static void test_microqr_options(const testCtx *const p_ctx) { data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret_encode, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (p_ctx->index == -1 && data[i].compare_previous != -1) { - ret = testUtilSymbolCmp(symbol, &previous_symbol); - assert_equal(!ret, !data[i].compare_previous, "i:%d testUtilSymbolCmp !ret %d != %d\n", i, ret, data[i].compare_previous); + ret = testUtilSymbolCmp(symbol, previous_symbol); + assert_equal(!ret, !data[i].compare_previous, "i:%d testUtilSymbolCmp !ret %d != %d\n", + i, ret, data[i].compare_previous); } - memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); if (data[i].ret_vector != -1) { ret = ZBarcode_Buffer_Vector(symbol, 0); - assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector); - assert_equal(symbol->width, data[i].expected_size, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_size); - assert_equal(symbol->rows, data[i].expected_size, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_size); + assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", + i, ret, data[i].ret_vector); + assert_equal(symbol->width, data[i].expected_size, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_size); + assert_equal(symbol->rows, data[i].expected_size, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_size); } assert_equal(symbol->option_1, data[i].expected_option_1, "i:%d symbol->option_1 %d != %d (option_2 %d)\n", i, symbol->option_1, data[i].expected_option_1, symbol->option_2); assert_equal(symbol->option_2, data[i].expected_option_2, "i:%d symbol->option_2 %d != %d\n", i, symbol->option_2, data[i].expected_option_2); strcpy(option_3_buf, testUtilOption3Name(BARCODE_MICROQR, symbol->option_3)); /* Copy static buffer */ - assert_equal(symbol->option_3, data[i].expected_option_3, "i:%d symbol->option_3 0x%04X (%s) != 0x%04X (%s)\n", + assert_equal(symbol->option_3, data[i].expected_option_3, + "i:%d symbol->option_3 0x%04X (%s) != 0x%04X (%s)\n", i, symbol->option_3, option_3_buf, data[i].expected_option_3, testUtilOption3Name(BARCODE_MICROQR, data[i].expected_option_3)); - ZBarcode_Delete(symbol); + ZBarcode_Delete(previous_symbol); + previous_symbol = symbol; } + ZBarcode_Delete(previous_symbol); testFinish(); } @@ -5541,20 +5430,25 @@ static void test_microqr_padding(const testCtx *const p_ctx) { length = (int) strlen(data[i].data); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %d, \"%s\", %s, \"%s\", \"%s\" },\n", i, data[i].option_1, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { char modules_dump[17 * 17 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -5563,9 +5457,12 @@ static void test_microqr_padding(const testCtx *const p_ctx) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 17 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -5633,28 +5530,40 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_MICROQR, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_MICROQR, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, \"%s\", %d, %d, \"%s\" },\n", i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(BARCODE_MICROQR, data[i].option_3), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), - testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); + testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, + data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[17 * 17 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, + length, NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -5665,10 +5574,12 @@ static void test_microqr_optimize(const testCtx *const p_ctx) { int cmp_len, ret_len; char modules_dump[17 * 17 + 1]; assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i); - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -6684,10 +6595,13 @@ static void test_microqr_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_MICROQR, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_MICROQR, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, %d, %d, %d, \"%s\",\n", @@ -6700,30 +6614,43 @@ static void test_microqr_encode(const testCtx *const p_ctx) { } else { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 17 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -6822,76 +6749,6 @@ static void test_microqr_rt(const testCtx *const p_ctx) { testFinish(); } -/* Not a real test, just performance indicator */ -static void test_microqr_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int input_mode; - int option_1; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - static const struct item data[] = { - /* 0*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 1, "12345", 0, 11, 11, "Max 5 numbers, M1" }, - /* 1*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 2, "1234567890", 0, 13, 13, "Max 10 numbers, M2-L" }, - /* 2*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 3, "123456789012345", 0, 15, 15, "Max 15 numbers, M3-L" }, - /* 3*/ { BARCODE_MICROQR, UNICODE_MODE, 1, 4, "12345678901234567890123456789012345", 0, 17, 17, "Max 35 numbers, M4-L" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_encode = diff_buffer = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - struct zint_symbol *symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - 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, TCU(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 (p_ctx->index != -1) { - printf("totals: encode %gms, buffer %gms\n", total_encode * 1000.0 / CLOCKS_PER_SEC, total_buffer * 1000.0 / CLOCKS_PER_SEC); - } -} - static void test_upnqr_input(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -6953,9 +6810,10 @@ static void test_upnqr_input(const testCtx *const p_ctx) { data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->eci, 4, "i:%d ZBarcode_Encode symbol->eci %d != 4\n", i, symbol->eci); + assert_equal(symbol->eci, 0, "i:%d ZBarcode_Encode symbol->eci %d != 0\n", i, symbol->eci); } @@ -6968,7 +6826,8 @@ static void test_upnqr_input(const testCtx *const p_ctx) { data[i].zxingcpp_cmp, data[i].comment); } else { strcpy(option_3_buf, testUtilOption3Name(BARCODE_UPNQR, symbol->option_3)); /* Copy static buffer */ - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, + symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { assert_equal(symbol->option_1, 2, "i:%d symbol->option_1 %d != 2\n", i, symbol->option_1); assert_equal(symbol->option_2, 15, "i:%d symbol->option_2 %d != 15\n", i, symbol->option_2); @@ -6976,7 +6835,8 @@ static void test_upnqr_input(const testCtx *const p_ctx) { assert_equal(symbol->option_1, -1, "i:%d symbol->option_1 %d != -1\n", i, symbol->option_1); assert_equal(symbol->option_2, 0, "i:%d symbol->option_2 %d != 0\n", i, symbol->option_2); } - assert_equal(symbol->option_3, data[i].expected_option_3, "i:%d symbol->option_3 0x%04X (%s) != 0x%04X (%s)\n", + assert_equal(symbol->option_3, data[i].expected_option_3, + "i:%d symbol->option_3 0x%04X (%s) != 0x%04X (%s)\n", i, symbol->option_3, option_3_buf, data[i].expected_option_3, testUtilOption3Name(BARCODE_UPNQR, data[i].expected_option_3)); @@ -7525,10 +7385,13 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_UPNQR, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_UPNQR, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %s, \"%s\", %s, %d, %d, \"%s\",\n", @@ -7542,20 +7405,27 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { } else { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); } if (ret < ZINT_ERROR) { #if 0 - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { char modules_dump[77 * 77 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, + length, NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -7566,9 +7436,12 @@ static void test_upnqr_encode(const testCtx *const p_ctx) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[77 * 77 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -7601,12 +7474,12 @@ static void test_upnqr_rt(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { UNICODE_MODE, -1, "é", -1, 0, 4, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 4, "\351", -1, 4 }, - /* 2*/ { UNICODE_MODE, -1, "Ŕ", -1, 0, 4, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 4, "\351", -1, 4 }, - /* 4*/ { DATA_MODE, -1, "\300", -1, 0, 4, "", -1, 0 }, - /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, "\300", -1, 0, 4, "\300", -1, 4 }, + /* 0*/ { UNICODE_MODE, -1, "é", -1, 0, 0, "", -1, 0 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 4 }, + /* 2*/ { UNICODE_MODE, -1, "Ŕ", -1, 0, 0, "", -1, 0 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 4 }, + /* 4*/ { DATA_MODE, -1, "\300", -1, 0, 0, "", -1, 0 }, + /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, "\300", -1, 0, 0, "\300", -1, 4 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -8222,12 +8095,14 @@ static void test_rmqr_large(const testCtx *const p_ctx) { i, data[i].length, (int) strlen(data_buf)); length = testUtilSetSymbol(symbol, BARCODE_RMQR, -1 /*input_mode*/, -1 /*eci*/, - data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, -1 /*output_options*/, - data_buf, data[i].length, debug); + data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, + -1 /*output_options*/, data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); + 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->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %d, %d, \"%s\", %d, %s, %d, %d, \"%s\", %d, \"%s\" },\n", @@ -8236,19 +8111,29 @@ static void test_rmqr_large(const testCtx *const p_ctx) { data[i].length, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].zxingcpp_cmp, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d errtxt %s != %s\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d errtxt %s != %s\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - symbol->input_mode |= FAST_MODE; + ZBarcode_Clear(symbol); + length = testUtilSetSymbol(symbol, BARCODE_RMQR, FAST_MODE /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, + -1 /*output_options*/, data_buf, data[i].length, debug); + ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data_buf, length, debug)) { int cmp_len, ret_len; @@ -8398,9 +8283,12 @@ static void test_rmqr_options(const testCtx *const p_ctx) { data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret_encode, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); assert_equal(symbol->option_1, data[i].expected_option_1, "i:%d symbol->option_1 %d != %d (option_2 %d)\n", i, symbol->option_1, data[i].expected_option_1, symbol->option_2); assert_equal(symbol->option_2, data[i].expected_option_2, "i:%d symbol->option_2 %d != %d\n", @@ -8416,20 +8304,25 @@ static void test_rmqr_options(const testCtx *const p_ctx) { } if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = ZBarcode_Buffer_Vector(symbol, 0); - assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector); + assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", + i, ret, data[i].ret_vector); if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 139 + 1]; assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i); - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -8605,10 +8498,13 @@ static void test_rmqr_input(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, data[i].eci, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, \"%s\", %s, %d, \"%s\", %d, %d, \"%s\" },\n", @@ -8619,35 +8515,50 @@ static void test_rmqr_input(const testCtx *const p_ctx) { symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment); } else { if (ret < ZINT_ERROR) { - assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci); + assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", + i, symbol->eci, data[i].expected_eci); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + modules_dump); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { if (!data[i].zxingcpp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not ZXing-C++ compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not ZXing-C++ compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { int cmp_len, ret_len; char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -8712,24 +8623,33 @@ static void test_rmqr_gs1(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, \"%s\", %s, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].comment); + i, testUtilInputModeName(data[i].input_mode), + testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), + symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -8806,10 +8726,13 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { debug |= ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, ZINT_FULL_MULTIBYTE, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, \"%s\", %s, \"%s\", %d, \"%s\" },\n", @@ -8817,16 +8740,23 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -8836,9 +8766,12 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -9275,10 +9208,13 @@ static void test_rmqr_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_RMQR, data[i].input_mode, data[i].eci, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, %d, %s, \"%s\", %s, %d, %d, %d, \"%s\",\n", @@ -9291,30 +9227,42 @@ static void test_rmqr_encode(const testCtx *const p_ctx) { } else { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, + NULL, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[17 * 139 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len); @@ -9466,7 +9414,8 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; @@ -9477,31 +9426,44 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { printf(" /*%3d*/ { %s, %d, %d, %d, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, data[i].option_3, - testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, - testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, - testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, + testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), + data[i].segs[0].length, data[i].segs[0].eci, + testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), + data[i].segs[1].length, data[i].segs[1].eci, + testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), + data[i].segs[2].length, data[i].segs[2].eci, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); } else { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", + i, ret, width, row); - if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) { + if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); - assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, + data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf)); + assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp) { @@ -9515,10 +9477,12 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) { if (testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length, debug)) { int cmp_len, ret_len; char modules_dump[32768]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length, - modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count, NULL /*primary*/, escaped, &ret_len); @@ -9755,10 +9719,13 @@ static void test_fuzz(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); ZBarcode_Delete(symbol); } @@ -9778,7 +9745,6 @@ int main(int argc, char *argv[]) { { "test_qr_encode_segs", test_qr_encode_segs }, { "test_qr_rt", test_qr_rt }, { "test_qr_rt_segs", test_qr_rt_segs }, - { "test_qr_perf", test_qr_perf }, { "test_microqr_options", test_microqr_options }, { "test_microqr_input", test_microqr_input }, @@ -9786,7 +9752,6 @@ int main(int argc, char *argv[]) { { "test_microqr_optimize", test_microqr_optimize }, { "test_microqr_encode", test_microqr_encode }, { "test_microqr_rt", test_microqr_rt }, - { "test_microqr_perf", test_microqr_perf }, { "test_upnqr_input", test_upnqr_input }, { "test_upnqr_encode", test_upnqr_encode }, diff --git a/backend/tests/test_random.c b/backend/tests/test_random.c new file mode 100644 index 00000000..456a95fc --- /dev/null +++ b/backend/tests/test_random.c @@ -0,0 +1,301 @@ +/* Test zint against ZXing-C++ */ +/* + libzint - the open source barcode library + Copyright (C) 2025 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include "testcommon.h" + +#define FLAG_FULL_8BIT 0 +#define FLAG_LATIN_1 1 +#define FLAG_ASCII 2 + +struct random_item { + int data_flag; + int symbology; + int input_mode; + int eci; + int option_1; + int option_2; + int option_3; + int output_options; + int max_len; +}; + +static void test_random(const testCtx *const p_ctx, const struct random_item *rdata) { +#ifndef _WIN32 + int debug = p_ctx->debug; + int i, length, ret; +#endif + struct zint_symbol *symbol = NULL; + +#ifndef _WIN32 + unsigned char data_buf[4096]; + char modules_dump[40960]; + char escaped[40960]; + char escaped2[40960]; + char cmp_buf[40960]; + char cmp_msg[40960]; + char ret_buf[40960] = {0}; /* Suppress clang -fsanitize=memory false positive */ + + const int iterations = p_ctx->arg ? p_ctx->arg : 10000; /* Use "-a N" to set iterations */ + + /* Requires to be run with "-d 512" (see ZINT_DEBUG_TEST_ZXINGCPP in "testcommon.h") */ + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); +#endif + + testStartSymbol(p_ctx->func_name, &symbol); + +#ifdef _WIN32 + testSkip("Test not implemented on Windows"); +#else + + if (!do_zxingcpp) { + testSkip("Test requires ZXing-C++"); + return; + } + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + printf(" iterations %d\n", iterations); + + for (i = 0; i < iterations; i++) { + int j; + int cmp_len, ret_len; + + length = arc4random_uniform(rdata->max_len) + 1; + + arc4random_buf(data_buf, length); + + switch (rdata->data_flag) { + case FLAG_FULL_8BIT: /* Full 8-bit */ + break; + case FLAG_LATIN_1: /* ASCII + Latin-1 only */ + for (j = 0; j < length; j++) { + if (data_buf[j] >= 0x80) { + if (data_buf[j] < 0x90) { + data_buf[j] = (unsigned char) ((data_buf[j] - 0x80) + 0x70); + } else if (data_buf[j] < 0xA0) { + data_buf[j] = (unsigned char) ((data_buf[j] - 0x90) + 0xA0); + } + } + } + break; + case FLAG_ASCII: /* ASCII only */ + for (j = 0; j < length; j++) { + data_buf[j] &= 0x7F; + } + break; + default: + assert_nonzero(0, "i:%d invalid data_flag %d\n", i, rdata->data_flag); + break; + } + + (void) testUtilSetSymbol(symbol, rdata->symbology, rdata->input_mode, rdata->eci, + rdata->option_1, rdata->option_2, rdata->option_3, rdata->output_options, + (const char *) data_buf, length, debug); + + ret = ZBarcode_Encode(symbol, data_buf, length); + assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 (%s)\n", i, ret, symbol->errtxt); + + assert_nonzero(testUtilCanZXingCPP(i, symbol, (const char *) data_buf, length, debug), "i:%d testUtilCanZXingCPP != 0\n", i); + + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + + ret = testUtilZXingCPP(i, symbol, (const char *) data_buf, length, modules_dump, 899 /*zxingcpp_cmp*/, cmp_buf, + sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + /*fprintf(stderr, "cmp_len %d\n", cmp_len);*/ + + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, (const char *) data_buf, length, + NULL /*primary*/, ret_buf, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, + testUtilUCharArrayDump(TCU(cmp_buf), cmp_len, escaped, sizeof(escaped)), + testUtilUCharArrayDump(TCU(ret_buf), ret_len, escaped2, sizeof(escaped2))); + + ZBarcode_Reset(symbol); + } + + ZBarcode_Delete(symbol); + + testFinish(); +#endif +} + +static void test_aztec(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_AZTEC, DATA_MODE, 899, 1, 0, 0, -1, 1600 + }; + + test_random(p_ctx, &rdata); +} + +static void test_codablockf(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_LATIN_1, BARCODE_CODABLOCKF, DATA_MODE, 0, -1, 0, 0, -1, 1300 + }; + + test_random(p_ctx, &rdata); +} + +static void test_codablockf_ascii(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_ASCII, BARCODE_CODABLOCKF, DATA_MODE, 0, -1, 0, 0, -1, 2200 + }; + + test_random(p_ctx, &rdata); +} + +static void test_code128(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_LATIN_1, BARCODE_CODE128, DATA_MODE, 0, -1, 0, 0, -1, 61 + }; + + test_random(p_ctx, &rdata); +} + +static void test_code128_ascii(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_ASCII, BARCODE_CODE128, DATA_MODE, 0, -1, 0, 0, -1, 82 + }; + + test_random(p_ctx, &rdata); +} + +static void test_datamatrix(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_DATAMATRIX, DATA_MODE, 899, 1, 0, 0, -1, 1550 + }; + + test_random(p_ctx, &rdata); +} + +static void test_datamatrix_fast(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_DATAMATRIX, DATA_MODE | FAST_MODE, 899, 1, 0, 0, -1, 1550 + }; + + test_random(p_ctx, &rdata); +} + +static void test_dotcode(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_DOTCODE, DATA_MODE, 899, 1, 0, 0, -1, 620 + }; + + test_random(p_ctx, &rdata); +} + +static void test_hanxin(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_HANXIN, DATA_MODE, 899, 1, 0, 0, -1, 3261 + }; + + test_random(p_ctx, &rdata); +} + +static void test_maxicode(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_MAXICODE, DATA_MODE, 899, 4, 0, 0, -1, 49 + }; + + test_random(p_ctx, &rdata); +} + +static void test_micropdf417(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_MICROPDF417, DATA_MODE, 899, 1, 0, 0, -1, 140 + }; + + test_random(p_ctx, &rdata); +} + +static void test_pdf417(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_PDF417, DATA_MODE, 899, 1, 0, 0, -1, 1100 + }; + + test_random(p_ctx, &rdata); +} + +static void test_pdf417_fast(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_PDF417, DATA_MODE | FAST_MODE, 899, 1, 0, 0, -1, 1000 + }; + + test_random(p_ctx, &rdata); +} + +static void test_qr(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_QRCODE, DATA_MODE, 899, 1, 0, 0, -1, 2920 + }; + + test_random(p_ctx, &rdata); +} + +static void test_rmqr(const testCtx *const p_ctx) { + struct random_item rdata = { + FLAG_FULL_8BIT, BARCODE_RMQR, DATA_MODE, 899, 2, 0, 0, -1, 140 + }; + + test_random(p_ctx, &rdata); +} + +int main(int argc, char *argv[]) { + + testFunction funcs[] = { /* name, func */ + { "test_aztec", test_aztec }, + { "test_codablockf", test_codablockf }, + { "test_codablockf_ascii", test_codablockf_ascii }, + { "test_code128", test_code128 }, + { "test_code128_ascii", test_code128_ascii }, + { "test_datamatrix", test_datamatrix }, + { "test_datamatrix_fast", test_datamatrix_fast }, + { "test_dotcode", test_dotcode }, + { "test_hanxin", test_hanxin }, + { "test_maxicode", test_maxicode }, + { "test_micropdf417", test_micropdf417 }, + { "test_pdf417", test_pdf417 }, + { "test_pdf417_fast", test_pdf417_fast }, + { "test_qr", test_qr }, + { "test_rmqr", test_rmqr }, + }; + + testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); + + testReport(); + + return 0; +} + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index 0495124c..89ee6219 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -1091,115 +1091,6 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } -#include - -#define TEST_PERF_ITER_MILLES 10 -#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) -#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) - -/* Not a real test, just performance indicator */ -static void test_perf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - int symbology; - int option_2; - const char *data; - int ret; - - int expected_rows; - int expected_width; - const char *comment; - }; - /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ - static const struct item data[] = { - /* 0*/ { BARCODE_EANX, -1, "123456789012+12345", 0, 1, 149, "EAN-13 add-on 5" }, - /* 1*/ { BARCODE_EANX, -1, "123456789012", 0, 1, 95, "EAN-13 no add-on" }, - /* 2*/ { BARCODE_UPCA, -1, "12345678901+12345", 0, 1, 151, "UPC-A add-on 5" }, - /* 3*/ { BARCODE_UPCA, -1, "12345678901", 0, 1, 95, "UPC-A no add-on" }, - /* 4*/ { BARCODE_EANX, -1, "1234567+12345", 0, 1, 121, "EAN-8 add-on 5" }, - /* 5*/ { BARCODE_EANX, -1, "1234567", 0, 1, 67, "EAN-8 no add-on" }, - /* 6*/ { BARCODE_UPCE, -1, "1234567+12", 0, 1, 78, "UPC-E add-on 2" }, - /* 7*/ { BARCODE_UPCE, -1, "1234567", 0, 1, 51, "UPC-E no add-on" }, - /* 8*/ { BARCODE_EANX, -1, "12345", 0, 1, 47, "EAN-5" }, - /* 9*/ { BARCODE_EANX, -1, "12", 0, 1, 20, "EAN-2" }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol; - - clock_t start; - clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0; - clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print; - int comment_max = 0; - - if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ - return; - } - - for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); - - printf("Iterations %d\n", TEST_PERF_ITERATIONS); - - for (i = 0; i < data_size; i++) { - int j; - - if (testContinue(p_ctx, i)) continue; - - diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0; - - for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - start = clock(); - symbol = ZBarcode_Create(); - diff_create += clock() - start; - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); - - start = clock(); - ret = ZBarcode_Encode(symbol, TCU(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); - - symbol->output_options |= OUT_BUFFER_INTERMEDIATE; - start = clock(); - ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); - diff_buf_inter += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; /* Undo */ - - start = clock(); - ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); - diff_print += clock() - start; - assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); - - ZBarcode_Delete(symbol); - } - - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment, - TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create)); - - total_create += diff_create; - total_encode += diff_encode; - total_buffer += diff_buffer; - total_buf_inter += diff_buf_inter; - total_print += diff_print; - } - if (p_ctx->index == -1) { - printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals", - TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create)); - } -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -1212,7 +1103,6 @@ int main(int argc, char *argv[]) { { "test_vector_same", test_vector_same }, { "test_encode", test_encode }, { "test_fuzz", test_fuzz }, - { "test_perf", test_perf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index abe5b05a..ce0cb838 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -793,6 +793,12 @@ char *testUtilEscape(const char *buffer, const int length, char *escaped, const sprintf(escaped + i, "\\%.3o", *b); } i += 4; + } else if (*b == '\\' || *b == '"') { + if (i + 2 < escaped_size) { + escaped[i] = '\\'; + escaped[i + 1] = *b; + } + i += 2; } else { escaped[i++] = *b; } @@ -1260,7 +1266,7 @@ int testUtilModulesCmpRow(const struct zint_symbol *symbol, int row, const char } /* Dump an unsigned int array as hex */ -char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_size) { +char *testUtilUIntArrayDump(const unsigned int *array, const int size, char *dump, const int dump_size) { int i, cnt_len = 0; for (i = 0; i < size; i++) { @@ -1274,7 +1280,7 @@ char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_ } /* Dump an unsigned char array as hex */ -char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dump_size) { +char *testUtilUCharArrayDump(const unsigned char *array, const int size, char *dump, const int dump_size) { int i, cnt_len = 0; for (i = 0; i < size; i++) { diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 5f2db45e..7098f122 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -133,6 +133,7 @@ void assert_notequal(int e1, int e2, const char *fmt, ...); #define TU(p) ((unsigned char *) (p)) #define TCU(p) ((const unsigned char *) (p)) +#define TCC(p) ((const char *) (p)) INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */ @@ -160,8 +161,8 @@ void testUtilModulesPrint(const struct zint_symbol *symbol, const char *prefix, void testUtilModulesPrintRow(const struct zint_symbol *symbol, int row, const char *prefix, const char *postfix); 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); -char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_size); -char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dump_size); +char *testUtilUIntArrayDump(const unsigned int *array, const int size, char *dump, const int dump_size); +char *testUtilUCharArrayDump(const unsigned char *array, const int size, char *dump, const int dump_size); 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); diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index e55d38deb031b6db4608821770d135a40c76f255..25bbce81e0fbda520ca439201e79f760b7a32b07 100644 GIT binary patch literal 140192 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 z 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

>AClpAt!BK(TZ&Vp~iqMZBb2m6uQh z_CD`{Y^9YSmgWA~;%wTALhE1j`XYrOSDfM!94G6+ybR3_cDOKmMhmgLT_v#`e=)O> z2of(?gS3%+*Q(+cvvbpy4>YkU&p}OwaiKOB`zdjTv;VM!UjWuMk}TZD+F37Ws5am* zX%J+wKQJumzoX1A)zWt z(i25A<5`ef?;5g~!YrZn>oO_%GCt`@XIEIc4KxA1i;oGXzNY~G;$gOo2Zb@yL4jix zGm^XCN&keRlvQdgl5X+?F(nYV`lcUXQH|@Qwd0`5i1Kfjyb|)Q)~7VApvB5sd_$JS zDDV(Kpp@&JW7{`lhZzVA@%z;7hntupIcpfV)T)A|Ktt=h9t)RgfJs9>PqKSga<>Qdl?o$26;a_6J!=}@SR zW@%!Pl|Sao<~W*byg&(>2jBH8fv@ayvNik0X@A*R-GTD@wdG&2MycrozxR+8fRi>m zeHAHENx>cV1T9ndM9H0v@MR}3fn9$PK%K?4O>UE})Ep?aJ}`r>SBBXV6rR1kvu>Fd z)FcnOc2N5tcCnaLPMrHHg1zT;oXns!OtSfd*I&bP>(HJr&I@2|$VgJ;e{_RDRqy@J zaMV3P#_>-rA=~{9&V!-(M<#fGRN<8Dl2>xzo3R+EN?89FOP-Q|ju*o0VmWb-b~YdJ zXK`=gdoR_n(UKb67lzP}WMrS*(N)px<30jH{~vhoT24_gPABs_hu! zvv`5jBj@$!rXm@(@kf*~F%W<}B;G!PLb#%#wEScUQ8|2)OK>8;Ca&V4}yUa-5hymC#9XzHtyz1*6ER_@`L{AjP zML~C!4U2;Pn&eoh&1nlJS$$lz|MUb*=;C)avgmOXcY7H`wiy>pycg4VmOI0}o`jO8s^5cc@RNIYSx(tPuq6QF4r?msfyd{?Zc}uUueyLI!XN&a zN`u~5wH4Z?Mb~Yefgs!5)5;H69WRkx#Yq;P-f*sl^GS;_S4SpXXQ8+LyVXH(5(Pja zSfAFvVhRi#IRW+(p8ub79t_F%zO4@RAoTv~E=BdvcRkKfP|OZV2^h%gwL2*8Q;o*T z8CT(r{hg`L)pCE;S>KNWE#p^V2%?_%6#}59bslTrknAu{TjrZ7#e~Y`yPhIW{%w# zdikZ`E=smeSlX=Bm_ece=6>3l!0Y7xy>Lt0hGrG`rknb236t7*A;(ltj+B3 zI9=(%ZPBMY^L_Mll})f-)CiE-;`|mX8ZMculigb0yT}QMx-E+-zM_0mg$Llr@ZDw* zE^8dI3tYT5WkkuI>kN)ty~omj%M271V!()3lf=H~fxKE80;btmCZjQ%D#TRD!08t< z-nngvD0Y4Al5DFroM?Rkkhsiy;l~EnBpZitdFt?1;kBoZD91jnoZi#AK)Bj9>lo!a z0PU0?ItuOJQy6r8Z=l(qKEGrS)Y0{w7SP|k(n;L)*?!77l_4w_5+QHfiaF+ia8sJi z-KHl!<=jQF&0fBJs!4X)V|n0eP)+Jq19*GE*Z=yF%6QWSq6`Cg8ROKeJX)-d3PeN) zgYoKL{t>>B5ygu$C?HuQPDj&Di;9kFzTwR8@L6fB2J<~QlBgUv*gJKCx!q8zq1CgX z(roa0O##~V=~55-V)JWPr#yI_>=*XrT(^*}4W@f^#QCME42~aj3H;>)~ zE;ziFIiUxuY50)W+L@G?FY6CSD&%$asbvSe_3Am;Qjh-*bsKXcDlOUy{QpDw-4TJ8 zg-v)8CCm|s-x8z_ZB)lrqlML>Za@vYyMLh;+FDvu(Pk7vDI`L4foelBoRmNl(@Sk# z6|jS;<7t0!BsBe$LrBl=h`^0{e_eWK$OB(_PD=TFUd1xkout~H1%7M6kn|Ak0pU;H zjtJUa#w#7tza<$<8COEa2&T}?&j$B$hCYv5Q_4JC!-bBs5caSN73GrZA7sAl8F29g zODq8Q@j)V&8ShdR*)Zxrx_YOYoG<9w)*C{O%5W$TE2ZdBgI7zVyqIk&VMo#P47B|Y z>VO#Sn2r=Q_+P!sO@n_-v)8JabR_asS{CG+mx)pT8ONbF?riF6y6Fz(tvPs1_Vi7m z3csv7yEm;Z>5?NrQ@`kZUc`Tsphb>=BYDb6@#H9t%lF3p2UdsAkk08%SBLPa>jlvK zi7o6m^`0u*sa)4LGc%W<+nqFT0zb;h3nPnA*bfdCo3zNH!Y6J(Ze(t7L*xBhxBJl99#I2H*eDA<&T3pOk*v$p8&D(2aYw=N{nyi>DQ&b zxZw`#*?B79HC;rx>BXF49lBK}F^j%HExXA5dTy70Yo+TCvV1+D$w*6FvRuxE0zIQl z<9b*HihNA*2S=kbU~A;DkV*UhB{*9;67CB4XzCh`K%|OO0(a%eoeM}fZVFzu-nM}p zhpbU3$lUc$tAvvc-7(naOk!B(_jQDq?h)4>xW=6yhww~KV`|L%ApJ_p14(~?T*R++ zf?X`Bj&0V0oqEb_;xuiQqJAOEvU6wQ(We9qwgUHT(P7G0wetQNrx!AqFtFWnaS1aU zLk>eo4P0opuqOnPVS{5m-FqVH`GpoFy*;;QdmsLojL*XjG0Ng|ny9uHLr=4%^L;u> z`m*MsQux*n7mC~Oy!<;@4k84oHc6S1-vI8c*&-7;PJ^JD*`+6v>){@r_LQ-VThskv zE+M;q3#Pzf)JgXr9};LSAU zB>E0&IzE7=X`%Q%GC?IN^iQ>Xc##^9u2rmPJY-r|$7t3%#x=z$0a!cE)gkc9>*+-S zzKmq~b(7iu!y=Q@zIOeYdRQM*>C@#mltJ3b5-UaQT(Jwl#cmlv+T-IW zd8$HY!pv^Jw7OH}F@W2hp$SaJ+DWk7pF)#*t{4FD@UNE`>xNt127x_<1#gPwGSnj%DF}%yo z-;16Q9o$z3_`sY6xWA>Ql(pz6k!S)TwGeOWfhM4UY?*DD(p#n0u@r~}RGYs>r5lha zT9o~)Lq&gUN!`BKBl+{LTh>GAnR1NG=H>z)=8KoD`)+PGbR1(0hxfaQNj~x-bkf!v z<6pEG)eCaIZUUC%P9yFjgy1R~6==Vgmtg*bB)$@nw9%j*^K&faI`HAe^g4D8~a78r89l{PU zCus}4fMWs)5UBL#=|g`fPZSUk@3=`xuv&+dub>|MeoF|Em~C6WdHHs@Ji{s`0utZ} zft;H{6%DWtzDibBqs~fQ7`PE~;VC~*WAp=6MrJ`m##)X@UbEJ_?1*}HG;1ovYM1ZK zv?{Qlz&3_Ryjc_HYh{Y}SAEh=8VJ1#5wkhOci6jVv}jT0eWrr%?k?}m-n z{XY;_i?w)Z4)|EC4;OaTeOY@-S9(H)_yMN(ero(5oaXWq?f*a;0H75#?b~OiwHzo!G&VMNw5?`x`)r_}Xx8LfR&X%37*y z=u^8YPpTRY<{ym3RsF@`rU*B<=u7^(93j|E{W@t{*Aa)BV;fy5o8JC*^M*A&BE)I1 zjaB408)YcJHfcx}Kt00vKf$2|LpW|Tni#SKe3h?4#uoV*Km_0P4-4f1C}!_>w(sx6 zYeaUIys$lWuOx?}95}y+sSMN6ql9PR*Xp|`IL!C+u*IfhC4jt$=G=Yq@*%fv$BJ8z z?nc5lBFB4PqErk1k=|TUvYPhuri_PeY~(M%GMK(7ngk_u(c&C#GG%PBEq1kkP$yja zM?2sZnTm%aa@F;d`2B}JBinB>`v1J)b7i1=pECET5#IP`$d?_}u?CwoKgyx3rhY_{ zn$Pn!JH5#vu!w_-A7xp}LE2d@Q&+of{O^SeL>y^WpH~qp-@AR~yY?3*BN-_b)+&_A z_R+GUOd7q%y` z$gD8Q*p-UiQgOCAGco`;bQ%tBa}P)>m6FcX55XGyYi!%kgLq% zl7;Sx-jQA}>3$cVjNJrdUmcoK_e^=+2DRmYU+nixqz=^bFKIly)Fk=MsJ^@fS8SJL!MgfjD7v!D6G}NONdJn{j`yv|+)nd#;lGvdXt z6?S#GZ8us*R1k69{tbAJ)qP!&HxbU+wt%z`(kw5N*KqD-<^rLPgmpQAM$m$=l5p%$ zZmmw!d8>;XW1K@nUYFHq_?-4yFwk5^xE(zXj#|HI%5($$6GIOGFDLpz@&n@KNFg3E z&^SY8=;S-$CP+e$}D?OB&zx!g z5ASa0b(J0>M^&jJl^TezPmWnypGtG>9W&6&c=dt$u#m1|!#COHggq8jVIfLXZ62zf*sRegPXera+!9DsuhKj;;woB=awkn!nz z{I>Fx`R^=Ob$0G}B>#9Q4R7FHBE5ZFJIHE%x`?IDi0s+&_V#>dQ)v0-bX0(^X#HShDlWoa0k zYj`XcLO~#Waz~_lDCj*I{aMfU`Ryz1tg{|Y^H<)T*XL?)m5~!sX&XQb59*ZOv9lsn z!dK(0m@yJOZQz+W%5D3SAS4htqp)U<4|rI;80Ul5fRf|^8BDfOK1z$$%pNsxlF{3S zV4`@;ppYVy-QxLNhH~`b;xVa+=g9)sYAKBHYryy&1z=hz01g8*Pqye>kSH>wNejL$ zGD9QV+`6lBa^U^X{^emXmS|bQq0U0U2@tOQiSEG2V?T$vI6x&g_gv6D68?QMnbs?4 ziy4%xP2?L8lzp%av*+18PtczuI!4jb#Qq}2=#)ic77|4Q= zR}`p+7!@uH33y11{DQuWg)*Yv>{~FHoa`R<9M5gyQ_qsFMa5~S?_8&_pF;r%RvKRG zbT5}|fVp>xMuCX);;nFg-Zx@Wm!ftT^7`u;-^@Xwtw7B_ z))z++&Q&HXg9u@z-l{R|4o3WQq$(npMVLA##z(9gDI&jxJ8OoCCeE;>d2+v3h>3w# zO#v`G?U3Kfq5!A5OVf-_q|jST zS&h_2BbjQqb=NeJNDoK3c6`-kw?C;VNGvl79^kW!zaoDDvjdg%ERh$+r2oAbSE_=v z)Hpgby(Po?3!gwk7rBm?_!JUv^==J05$8|gE7KIU{DDK3TEr}bfybv)UAU?V{Kgqa zeH#H=+R8SGn16{={F&G9f85R~eat^gieT>iNtw(&@sN6O(ACDj(Q||lq6IsOR30k{ zD@PNCG_y7n{#}?G6wlIS$|p94apJ{X75N$A-DD3p7xOA0XNs#em?PD*1JPW^J{zdGNAI#-8#!LV`PDlH=>X`nlAsbfh!V5Cm`0%gz3Vx`Hwc2?XT%5 zaY(x&_UCu+e{gS{LjoNF?+u~%Pg|mCap@xU??{4lN(-cvmf>%1iVw(eBNH@@2}wl> zHwS)APk)U#(6CJ7Yk%Fr>tL#Phl?8+8mH;cPcHM)x8El;hI@q3fd{+u!Md^)(e7*R z2h3$Ms>n@h8WtUn3-ktt<2{r-f8hG+Hxzkx8^Jq0*$exPx~Vp@2+J>#3cUH7zZr`; zxIqs>BlP!&rvpok?(ZVy)2@#woq29t`VD(4%aqNs7N^zkv9I$e0XSpYy!y8e&|Av~ z(~U~kfKAz$10^{V$UsXMj7C-eMkCqM66r4ii!6kM|tTS03Op}u0w2Me>$g+ zoR~mC?()6udXU+9!GkmRBwYfS)$Sc>x$@U#CDdHs_A^!PhV zW1WGMmrov9^?;wWaYomh@JW#%o@#tnBlM|F9m`V9Jm=?>W`AOd!`|0mpM&mQw#%z= zu+a^}7n(Pi@HTzEY(26;@)K-NseUrNG2_yH+kz>GQ%^?cpXm}juA)?Z^& zd)CY83Su%YeV1N2hN%j!jO^Nq#0QQ%fYEVT-9d*!mAj?io)r3#!-+kkNv`b_ekGF)2G#bsb(Dc9JU9X2SYZUL!p@;XtKtc%NB7iqQ#1QL$71h*=-s8( zEu~u*CCt!1B1F^$v}`=6nGu0vzHCy4B74s)D?0*?;F`(j7JlVh(3{X~25Wunab0^i zo-a8B83t?jt|2}umKUl1zs>2pP<8f1(*2hYhnbw!L+}{qSTIZsY(~}_{3x&cvz5Qt zDpszgQ?Rg4%cG!YtKbeCLnlSTSl6`j&YB9(H$V2^{}qJC4y3b{T1l_MtXjcK?z$eE zH6~ry6wQ#7@kojMjMz{@5c{B#uaxekEwv*)h2Z- zU=O5e97zJmg^Q7?&|`VM%v+BhwgDhwg?izneI_M-fX4Y_TgDUdQCnGNM4}{Xq5JWZ z@4nwG;aeQHA}x}9FJ>9iGC>dyRpv4}Jf{*Anf}!%*biTQmPbK~6MIuM1dUftuObz1 zs5sesK?tFYRx`TI{GaWX6i(vdk^*V)Zm7hff}VId$d5Sx%U9*b^2bwiU5(m?;R9rn zu@P5yqO#}x=)nMfte^=JsKRq9QzMURWsa=vpcO$M(+OV?_CggK0|)dnooJl5 zo>e!~C8*9XNqJN$$ZHLjKn`7L)Czwqn_SwX?A3ATEocEJekOtdaEp$aB8yP9wKr&o zvs8J()pwk+Z|O)&lJIvwIIi`<=#^?Hh+v*=xJp$BtxE;*5l5e4B+kr1F~stV+8?!3 zN>5pdX7I*igJ=Pi*|oo)Ge&5PJ|}>;fd_zAtWHl~k9|JZoD`XRYC~HZp|LQrFe%z! zI=(k=WU`~bp$n%UK33@**M=&?(V$KZW~qub7FKkllo9Qr(0`(TVhN}#a8WXHp08{v zaeKi)eeoQ=Em%ZSfrBC!o(=}@KC!7ztLvd?JO>y18v@tTX51~zKv%DI%TBtd=e#+| zjzLLf6!;j>TgGIZ<0ItTLqmLyOwYC?#C@vc6kKPoD#n^avCW#Pl<}hX!9)P`X0iGM zNCUj+R2A3(g6sz>ZO0JM)<_rIV0UQLyFPd^JLoOKcK5`LAP$H51D_2j?=D5^fzw@m zx8;|(8VD`fjpo9y-T=Pz#{iFUtWc;mhoJ084_XM;_fjzqGH;1;>zT+aD#*FdPRa5! z(ozG16-s9@2n)HVKKKE%*73HxBkB_q;rWnMHsC?ucDvtYdrOWDog>xW`)$Ku3xp$I z935`Gg!rF+r0I#H6^=K8qAE^ev*z{T5wM&beJZpe^5gET_b$#`>h=4E)RJ;bW~-wC zwM>e-GjSV@v>d0vZJ@s8n$6(TB2XNIZEuy6o%5`zeIvB_{nYBdRV&n^<9P-mD54Ce z=n)xlKx4%xhSDN_AcfGLl{-9Y8E?r_VV4=|q}OV>UpFk)-kK z?63Nl{jBiPkY)-lE-4{uk@eYb{JRo3xUaFJpPgiGRsI`k@;XRg2}iPbso*ROP&%Qe zw=2kvoLT!_1Jpf}w-l4$wq?xYbNWlgN=2^j=0TQulXC()#HI+nXAW40H*Ie-<;24S zdnVQ>P=FKrP|t+b+2Wf?dI4UWzdhD`p%w+)EC%zvQ1`xnTfbNY(OXwh#ty}<#~i@Ui$@3(%$B=fuq_|x(spE z39Gn0XMN{e`S=4!A@COI(dk@H<1NX$316ZS5htL6jNh+hA*t@{w(TK}3E{UQu4p%l z|11F_=$QqNVq|WeNN=2G7sJ2G#YBF1tShF?Allno%fA#sZ|*j$D!<;8lh9d;9vYIp zyur=Jnl*FL(V~gLia+5e94K_uyE08wItMjR^dgwjeWa!XspY#XsJ!0-MK}KwS^Fmj zmw>eZnh}VH?01&&$`;0uiJ&8EabD-zM5jK_Zw?9Dg?=GLT2DGbD0-N~shp1E537Ra1`FW80trfPub zC+CG?9TyH)t#`(ym7e*?84>pua0nVFqYk)QN|<~H==c;9T$yKZsxqy-EK!zgG?k^G za66rK=9lf@)MhggB}P0fjkz@01yC1;P%tV=n#7JF94@sg0o_yf@J2WCh1)g%#S`j=yE zb({W+Jk3|cd7SBLgz-)cucrm0%B=rYA5cnp<2ber^C^8$9!^83=mw*(J*fjLra5dB zz-yoN0dd`zQ+n*tjlO}Hdd70LNS6$1e#4U09SOaKsi zV*BixBXyxI-g9vcePK!LV^sw%dfP zby`M&)2MQS<3Tc+Z5p?}y5XvnAX-iij!6_jwmIq@Mp*o5z&bfX^pO*oz#-^lYS4Q* zzhMSWme1&^U8hC?9;QQZ=&y|2tmC4lcRb1W9s_kQu(oQ!j>0h3sO^F%)>-GmltnrY z1?rkh9GGBTs7M$Km&>V3qKT%|fLLS#d-~u!Ko6nxF^*IB^J2=RT_)n_NOAB!@~NM{ zSUnT~2jnSlYLGQry1KU7o~%n|^MdLQKowp=x@$6uI3aKN7)EW)6@t5a4*BmfdD`Ne7bmMQcH4mUS_^Znb;V?+!BaIW<5K5kPn@dzsH}t+=|C;(g#p>hAuxq zPjZihieUGe-iDFBAnw#pv|S5&ia$A4P2^S1K@?;THKn}KEIG?-2^U+57?x+s3?OisNBs>+emp6v+|A^}aVX~bauj+5%ju-l+q zEo^0jzL`oa55|v@tcw>nogO{?C=2;$KE^oO6*ye5Vab9J+a;Ye)!CMi=De*G#Q8hqMs|Q;Vfk9vH_qq*$-1h zAO6~fs1|acMNeNuXJz1A23K*(PM*_>E+a<#RvwUbYX=j@& zf|Mvd{uC_i`ohoaRbH^(gPZ0?JTJnRf`Ce}X(`+14NC@Oh9bQ4aISUEc8wkdm^IG-=;v_7+C@9=f#OM?QbvAOEm0BBc z^IXv)7RY>v3C(Y=-pKT0(=LEJu-*eX0MU+u%t>%l0AKUE0p=iq{=3i_<@7eY9q;Kw zAh+`J845rq))<(I(=*J#a(qybgkf|S#;H)ViMesi^Zv{AXJr(0@p!XI+V{w;hGD8v zGTfbOPE!KNOP?eSVS>QCcDTJ(DoF#HB;xhTya+80UdhSHZz!UF{pBeQ#)G1MFSwSCrUQU&;)XV(93!7|K(9`!`*V(D&kzUz(mVX;=Kv^^JJc*=M{(dxUT6ie=Shuu8GhJK^; zi?ob&nE(VO6$aQ^htqY#98N811E#mCN$FwFkNAVJ(KpuQdU?xJvcAk9{po@95iwZR zw04BQ;siQUtK8$*G8-n%xrV6bBjRn+bEQ42inPtl>0=l30W5|ZR?w$Sfl86>>naiG z*(YMhZ!}&3+s1bNpGGLg>XKE}W#ZA|_=#9W#%}ewt7ZuENJ>GhpQ{N(j4<7SQum`> zuza4{-r%&wE6whegbmoW{ulHA>lFjBI|j}+IEnoz^$uaKe|8q6eBnDqwox3N8as5r z-4v|E_v=eA{u^(IW(?A+xaI|0*^|-3pNWBPRs2A-oC=kHx(w4U=d=?vKz#b>q-P-A zSzVrDI&dw6 zV=BA{=bcj(t%Dm>KY`^~P9VMS)hu(Tdi7`K6JUUI7~nYv^x9mo=n>F*w?m8P`Jm{? z$xY=aqs=Q);0eneSVn}b2KH`l1Ki!?r&+H`JozZIqUCCl)D`(pFzkE_*R z%_&U=z^(^>?NPM*3zPgmNPw1ZVhTm&cJGivubb_%yX8J90U-;8iTf|ckfG`_%#nkp z*KZ0G1zj2QemUuAd?p)1&v)^!5Z}HsU+`fj0P5!2_V}#CoA8f6WG@}fWOw8pX%zu0 zykNL5)zXP{jYlf9TAUAl)vbHHR$O6a5sJomztU)vf<~5!2a=5F!*WUbyoxJ`&b=Oo zvC;XD4RGTWbu)=G*x8>VTxgISagLMsx*Tn5W}ViNHGx~B1GdEER~&K!gziMbl;b68 zW>l*=C7@H-_+lN0@;nSE;?Is6pWSo`^VyfoCt?bcW7}{N{!>Hqq~&_3M6zyLtwfKX zE)`9pV-0H(e{#aeNfs@f;M9hq1Dmf=^WVDX4sccF=kPYUtu}gDst#jVvl~#v@Nhr4 zWG>zHoZS9tb^n7_s?W7BiD^27iN`%eIACS=4;mF=E{8+^0%bEd0ldd82r9`Ys2ra# z2x*(c)zW0$t2Q2&N=zCwj3qiZl3|WZDCJ$~xh5aRn8pj@^w!G14V@+hj}~VTQ_M3K-+xi9p3}>H$zMrWg)bXF^xZ5TnK%Gan>)*eU4F z9GPdWP;$2PuL!l*k46{eq&(4bdjk&w)2AgbQ=fs)iIh*N1V`0C1VdbsY8YMnnf~qr zieyxji2XVhJaQ%_m}!@Y6zIZ27x(2(mvS)y-=Td)q>(+*i;>8$Dg{31$bzV4qcX8G z1!;4Ux*FgJT3x4l%sJKI9Q9klLYI4J#S=B}=i)mT;rn^lak$q|PNKnmnB7l+sgg^S zET$7v1Ts_;7nCWck#VLsDmDPI*!^{{?6QKin3L~s;`C15h_jmC>qU^=fcuzDtUS#T z1tPshf8yj4PzL%!V_m0c#Azw(tC+GrDL(!?y{HO5V&owqxS-A6=84WM4t#w%*qy0+ z!!6qI%g4*KAtm*yG|?&HXC=#D*|@jTWE)v{vEe%`OI^D^Q>7arNwXP4&Q`kMF2uf1 zn;{7;ZwYcgvUciF^J2~Zb%#;wXFR66iG@cPAQoU`)FJiFR8)rajX zZcTp4kz`Yf#zrM9g_0RkR5%7Q7#>dvY^4Rr3$Gemp=Ex;PB5it(0SsU&YctpT34Ja z={Fw;{B$a2KI=fsXrE8J34Sn#xYo!O68v3a4NupvT!10p1jC7Hyz&B!Z4^P3zj4#K zFpgU2&l3#ET^C-;bEy=_ zXP3MC|1&q_%PR{711ru~;{a44#*FS>5bV=e(KN@hiJwiR&zpxbLMEXJA;!j_IIzpw zZ^Z*3Z-bhAeb1gi^xN5=l5Xlf|Eos+mC4;9obNU3jpE`LKft#@2r6cC!5Cf6*pdqT z%(7W$EW^fx+&w!t%luUROy)khgJ1*phBVSVMN#qmVbAZ#c;Hb8d0o!k2%80~LI^zj z?FNwMtM9}y5VcCJt?mYH>8O*geIdY7)aqi;*9ZhVpWBl&*TG|6Ik6v_xA*yT@~HxZ z)Lz~rpJO4)t+BYrn*NLGJ@PJ_lMhy4Exgf6lT;>=v8&{@E&Uj) z4K#X5EY3w?yxY7dY#AlcF!-SUcZ)ahWL%q^J=ep~pfRB#h>T=7K8fPR;8O-QQ+B?` ziepoESRuUlR~Tf+ydnN4+&YN(Yc~NHZSoK*Q6-Y9gF~`hMS?!PK*+zj zFrI?=KCR^-jCDXXA+_>6G;(|%gYz-UmDMq!nX-L7)dZ`gGKRF?I(1Y}F#cu0MnZNq3d`+5RzE_o z7kD90v{hc_zKw>Ti9)g&ts>&TZ7PZY!!FOWY7Sc-muRFeYB#m=jL5jb2(J+GEH;~W zZc`L^(QPN5pRdSr#AnsIq5&6}&(-Iks>AJ)WA(%h4KH-wIjkx;jd(~(dr3%xNxHcL0K2>XE;!Bl`5c%T_+&qx&v^t+8bZc3!tH%N z4%NN!9oBg+m%c-dn;w@)Ai@cwmRqIfj>UZC%uZin$=a6*K+JenMokHpd(Na*OBy@W z60cM)RWagRG|g2d9%XF|;qV0*B!=r~fIRDW3IK;4!;gWou8jOOgj^V=0gVZkp2o}9 zlsU;@I7#yJ3DZzQ))=DaXB>S09UQq~5Z7ojp_kcQ&8Io4I5pXsC+YYzgp1il&WzOe z7gr^f-}z4&6WHRw)v#f^Me8UO#fll~Qf&&Osf@4qF!41N5az>D?JDbmu5#YfaIxp| zW&+=F9HJ}xOk-Q{P#4IG^^OaixR?v3vDJ4sj8<_XnO7kT^_V9hFMR6&8%A8_ddKgB zhV(lu4RUTIDoo%7#9U$Ahl7wx6$ZB(PI)N}czh^yJ5`EZ08eL`7) zTZAJhWf9@!n&LSXosT4;No84ibuU(l>ZlwzlRN5)#RBT!7?}I`DW}~&&lR!o zL8Xlmwv|-lDd>!*ACT~3z{w#Jm&wv?hLn^{^~VFg>kox~q2D6{LketH2 z4yTRoD#8#K0^f}1>Utfv4)%h3^{8I?5S0eTgHx39?zjLwwFO70TP~|cs2o-NI?0xN zLDk|CkR*61XOw9~FLq}qoeGJVV`(lBn%*YU>@_KA39~}lg#p$C0s=*0l6+zFPJs}Z z&%aIrXD4r%XqsQ&!%>=#sR`+es>P(wT7QmYVhI4cJ&wKHD#~VPVPMB^HEQ}0d~s45 zDe;1*@U?Hk@y3%cH-}xJ&Q@2Ig!@xQ9u1fj%1{}(+&vb@3?zu@i@lLXxh=rQX3VytKgVdq%T<)E&7VvIA z_VuFBR5U7MJO0w|lemFGp6flYb_7-BXhyy$J8kZnuB1)43p*x9ZVWP`yc`k4@I(&; zZ|zdy%8UaDHIMwVV1er!b@>Qy$GGm%QOz2mt4O>jlp<{=22bv1w~MnPMzx!}^I`Tl zig(Avc4sA(nSNq}pH!kx9k&n%ENNJoNMETX2eaZWq3x1n@9~1kXSNkvmOQ$iQ=fCx zUC+4uxNg*THtsJ9j8RAO&fJvxC_P;7F@B!{aAeeD3+>sObqnW}72|2ENgu^tS~$Q>MJwGJpEwV%rP*G6^`<^=oH|Zl!33hT z2I)kKjJ20ZR*DIG3gF0*;N0+cj!$@xI2rO|^F#e96y~?H#;j6`&9x5ZeyE*&pZA7* zX^%%7+@<}y6zb?-qtv2Kv#;4>UF$9T+t(Drd_Bpm*7~8jqRW~%;C18b#_Bo$s~eFE z+KJ}snI(F%P^&{KSOFOHIH9?jJ`~igh;;5)#edEm;4urNXILyuvEQGf_BliVwd-P@ zK%e;IDD_(zV1jO|V5Gz=T@5(W8gs%1dSp$bD|GM&^AAE;oyKVRk*zyCv-IF@!`Tpq zG3hl7N@~95}|fWFd7n%5=o3AbRp(f|Ivi%b7V0y$`FdXMB}3&xJI-{y2PHS7Hn?PW=$ znLSk$J?#py9CyFslPIirIOF|`+$cH`X)+_knptRNVoBorx-Y)nppRV1tv)Z!08Qwi zNhq!$JvTH%Umy{_?Kut!vh68SfyYc!E}@P#a7qZIJg=V4gvSU+l+FC9TXTif#Z0v( zl;-GBJP(MB+abwcnlFH8jB*(kjHKj%K1Q8dcV}T_d1-;0W{6$9X((}Et+P_ z(p#P6j1^Cn62P6JBHDJZF=&&X55B&?DPRBy5&im(c?@And}<;pl!mNZnvA#MUnA;t zeZJmXLS1e;x~0%ug{AL2JPDB*RMYy_gY21MQQi-4!v7p%h9;ozbOAs!KeHMb?~z4K zhx(H5fl9;){;A~C{>G@u8XMHxot^nyvvYiXY}vNdJ;XBUG>OzUB@e+VEDr-zU~?(* z72S2q>nx%{S?8s3^)Hu-CMX*bI`FHmrD{V1TQhYBB6st-(N^m-U(}) z3nRca-p5o~o=OVXOXfc4K;J^)&c$QI5c~j?f#WBda0C%(793{PZ73f7u+lVmZjHa* zChQ9N(U7P~EP7^bJQ}QgKzsg(Xy#q9EsE*b%2s0T1*>!iT5N|xido+mxv0vYuq|Km z#Yf`WFxuJ3JTHOyF`2=4f4dJ(W~bTqK7 zv6YcpcO2q}v8y-z(#F1sEfWxW-J4sHb&lO;J2X>aPsEC z!>Ig?7yD)@I-%RWl>%>U#1D(K=;PAve?D|RGQjWn4csOJArk~4534tRAT13zvFonr z;$qi~vIJ@G0~XIIBc>|(7Eo%lPW&WJ+^pMbR;JN4jnV0IWio0UoFC2+m}TqsQh5qX zMmR=bpr6RY$nR^92*#(!?z3kRxzJHZytgg{gIoe0kLmC;vI%i_~6ScFv3mG$ydh7?{IAc1ZIS}%6g=tYTO6B zJPD%&5v?PdHAQS2fs0I`G43z-jw9P^pJ1+hXxW>pqMaZ7n+{z0n8Q5??HiUL3}^7V z>^M_-5&}%rWQ@w$hYntC@rA_OYt2IGBdjHRwOu|%?qSwCJ+u0v6)(gZVXx1zP&G2o z!pR%y>}tL+*epf^;rFFU`10 zEHStxFSgXz$fKZEe&v0An_n>#<9=en21RhDRv7uK`prK9_Ak=b6ByQE|BFsvmw%pn z8kz%Q;xd}Noueue@%>L`Z(gW+(5N;6(2a3-?eAx-4va#{I5oa_GXp|zT>APNhG**g z23r1OR%iS>n!OWbR%iIxFt#s9QMbVw&Gr)LmwZtH5-Xg!@oxDlEK|zJ` zuo=}P!P@UUiQlD4I@@rc<{aF9U_m+IQ~+jVTt@Oyi^c={kUeJ+97A7mn-$*}T!9Qf znhMJodKfH2#jd*uI{=B`*oV6gCe(HETPHB0*i4WTwLUg|Qg0H0J>nc>CqR#@s+?Mx z2kdk4fuo~5Iz#3846!Tj@;R%%?3^E~=kV*FftQ8bEL&AgGghRcu3~(z*PtQB0XhOs zQ3*lgrO9=H3NqV~Z-ChV9G+SuhZ7#Rz|DI?-l04hNWDbFR#%gQ_X&`GOXYg#xgUpp z7~Q|nK)bs}DBFf8cX!zDRu@mRpT=#{5Hpfm29$l`$r?^1oGD^kFZTK*)q>AMOoEj7 zjUbQM7zG;;$>mZYz%f>v&>MTusZj1G?%NTI1%Sbhn+%J`dIav_uuQT@7cHElgFWuI z$BW&-HBbXn2~GAFaQngb-R!PO8p}KZdGA%RaB&R&P(RRcg>*Dh-m*2UZPI@EgpvXk zDv>a4&B2{Q(9nseIWYtP>}axeRyVB7-FF6~?vJTI%(;U2-}Gs6k38XYIoIw=Ljwbl zs&X#@-;c_9EN0FE@HSE>R@(-95#h_dkeY2Py^$n}f0RhyxB@o_z?qd7Y5Xvk9#4>0 z?Vfbw!v0z0?a=~9wBMpt>gOh?`)8GFAV|xIK>Zqh)$RnCnY4&A(o2pn>^Jm$>^cSO z2h9^iMOH%G=7OKgMqiu8M(1~Uq&=723}E(AeMN5q4A;qbPI3VYdSAnh`EXnxc&3qV z(Br-X;4&7Px3z&c{nJuRo~xYR**dZP=wcQExNG|CM9u3~YF{gfLjIlz0eH!IOjxR5 zs86;g(t+x6Lj%LLrIJ^jjc<2X(hruI_76(1JeXE`!0ph*^d9GM7vvvU$wOf zkm>^vZqwa zAk)ZZ!NzW`g7kh|3gZul$^+7}B2;AKsn)Z=g2`=J9=lktcWe4-=n$z}i$n&2XuZ0e=>!R3(BM?>! zg?jTpA8f%vCe963E5W>vVqHdC?`rponib>6r-%kuvU%Eh>Z*Cos4-n@0R2Mp=`F<} z$GOy;bhwMr$Y9g(0~N`a*HWwO72FfJpNB<3?vaYx3q&v4irHJ>r+MUAM*|zR5y^3N z88Cz-Icc@VpQnMuILks%@pza?M;z?gXj>IF)`~(l!adW)#Nk%Q*!mU;a6-MEqxB1; ztQ?d`*44?CQF14kB-m76ZyG&$P6JsxB(y!RhQRvHjN~6z$r3T8mK?KlnZay`O7F8iKvx2OZAU$Za#V z9%``Q+FyrL^CU$E4yjfbp>qKNt)IzasA*nB+*DGinXsYH0?x27@Y;Nl97Uk%HtoRIF40AD}#aj%6j4i;(f>ueqWtcCq zj`O!B8GF+U<1r_cE#3L$Kk#eOK{ z9nug#;0)`1Ca9S0PC5ba-lDofNi$*d^-piVUa-WHOS~cY3FOaww%Vqkce!n`+=Cvx zO|$P~^5rk`E%3MvX9lb@zf1z6jYuj-0wW;A8BWr`>{h3v9X{UE;f%q4H%YBXNlT#;$z9q~4|~dCxDx%dOc4 zRoYME_A386nU_A~mY{$l|9EmQt!S)4`aUR+0=KcoDxFdW?lBJ>*Wz!4H2Kh3KFv5w zWp-mx{z=axr=>(O^n$o>XbOX>y^m6`EqW_BJHg2UO-E;Hr@@w3f}a)wQD>6M-A1!e ziAeTM$=tnjt$i`yM{pkr@AR-^RJxG@fyK{n_0 z+w)EY_JVVTXy`N@Tsy%7;fJ?R;iJ29LW*;;Ls~`rr9iiI-K=WGu)qI(z(l9g;WC$o zfoZQxdgQN63fWxNkUQ^y3t?-|&@DrpDsDh)8S)OYpWmlEY@@TJ7PUrbquD4TvN`i+ z+(<-95n_?rDR*5_#z2fXL`wTkLazAmw&x!hVfV$-BO;aH(N6SVcd;NMxk8pq4ol7mAGd79fx~xpnOi382MFK$ zz7$pQA0t9G3#|ad>FZ#FIruV8pgSj5R8{E4U^4<7W|g>H%QyBK%q!2_oXxnU^tN93 zdH)#IGkYBSCb{yGJN7RLmH7?eNZFQeRUzVA&7SReIMQo|q$+5+pgW=!eE(Pxk(OIv)*1#>MRnArM;q%$zuK&j_; zohC>Z`(a==u1&WwMI86ZQ(*x;K3E`Fj}qs0+Z?@bb?;4BfPw`Pe#HsmPM3ZQ(DDya z%32nI_=?LM4NZ>lD`(T3t|ru5ufB}gPutOpZJaepTiyX{KNyq%6qHg+LP$y$kPilq z$WrU91{+$Y{RyU=7fshmGMQ}MtEFJnEU?S$4()emM0yqfJl!2>ia_QogX>?!ND66O z6D{FRNGW{`6p)8_5*r~KgNK<9cxca7z{ln5d+mm#`G$;d0PF9J)=RM`-10pl40Wy3 z)ihKM9QVhZKUO!> z-QfX}*-h#R!W?4}Up2vmysyI=TK4;)aTh$m57E&OL54zS_OqP*+L@zSI@YLPoUNj@ zT-nWoT_Ua#-ILg~-%nUs@Ue4LjWvZTeJH3{R*|hE688?aNxFZ$&sKvq3YuL~0T;)& z(+S2%(tG;e-;BWjVvXf0_jO>J-D_m9v-jnk$3w!(x*2{tH&1o7;7kYpg0_bIZFN}9 z-W~CLHS^J?Od$=Nn36a-@LC&S8gsRl#nC!+xGl62D%C6?r0=!9XfZ#eTU7BfqK%UtRz-#> z1ox#swlzEltv?zKv3he9P}RDqE=@pd9c@!XgLWNHnUu%tSyo468u}CD6ndfB4kd>l zrU;sCVm=(G3yG7~lL;?UPOYZ$a25xVoqxNa2DhStm!>tSJH02c{*#HP3bsO3+0!dz z6IK1m)-uLtjg|QnFD3;5bdh}%H9fUtp7%iIyW8eAe zIbD|MS?L@meyOQTw7EIqr#29Q?bR+~-a&=_c| z3?62pL@bWWA^W|^JdP0vd99op-D~NZn7o6hkX}VKlj0};Ef|BW3c}?c8N1F%WDtd% zW>`UqMK#q<%eqh^2zL?%&UOEllmrKQ-B{BOV>{C_E<_@3eS7T`jee^T`W+s6~Ij_WT@t$o_)1O#7B$Li`IO#4c!=&1t z&-YfH!H`DapLqV0F;|dC-2oboV|K#ldy#4&oUpw=38}?1ihPLVHh~*Qb`9*yC~v2b z2+drmcZO~l6`IG~kkyW3{Y6PU$d()KrYd;4e%qyTi?NYaeJ#P*9z@a{NlMwtN5uKV zlJOG0I$c||9fS*^!dsd#8$z{zhaMZTtpT8d;mku;08>LvWp;EDZ%VCSM;M0zCWNS5 zh%v;{xicl9}DVY#MIat)N-KPXA;X$t27I4_$ZGFxGRL|s3wPiX)we!V9|HT8~ zb)!*rC39hx3B)6aJZpK}w8179C17v8V0`m8Z?nTsCTm?vW+~X5=wd#m2A!{QXFcBG zLdG^xyz;d$sCr|%k5(EBP{2ur(;k;bUClwb;n%$l!7h*BMV^}zEK8%h2Mr~xyosiJ zQ6K;_7VA?(O~P}AK$U9Lkb~}$esFX1*yx0kH+ATCu?=_R&1&Z8$iE6*!lVa7@$X}- z|7_>alK_>)0K;A5-X1yG9cQPHH#)uG3aM7WhvLU4d zxqj~&={1Yo6aZyL}fCIcXrIftYP?d_f*CX-Y@98}JUj z(E)H>31~ol3SyuXLu>8;Ig)})3pTAMW*AYk?HoQMWew(Uy zVV%GKb}FcozX^FQp?uIv>mMNnj`&Jv?_hE1n&rHcz@2Nd70%a*E5O|^ws{!C6Io{w zOst(DFr&DPgd3&w_5a#MRv1XB}3&$_CO3V z=FwWgDda(C(anptcPhfN#T-p1*sbeg2&-b~qEE3&MdG+SEo*Q)L zs3Y=!G@5%`YXv-5bF>kp&JdqSuy_R35Wg# zQStPUIF?t|`&0<~?n~wDc)FLDc;RwT6q#DU#Ge zc`-h9X;(?RpE~#*Wn%DnOlc(Num^Q8ATu-h`_y-}ob1qCtvz|lc?d;~qnbv?D~A`N z56->nrj&BB5{#05zwtT)98Km^Ro_jq1E6&7j#TJQDEoIJ$idSK(Veh#r21#G8!G>lUl76~MzY(J?1c|CnSxWM7?Z_nk{R#rd2x7rr~+5>(l zH^X#UT?6G0rXd5aEOAdhoDdaDi)UAC`Nlorbi*?@f*`88s!bK`(lQlNKX=^udE(!C zI5p(>WLAjtE8q_jFbMQU9mrwDsDyD}$>29VM0x{f>Z_?a1-;u05N$H60D&J|I&t#| z0LE|FO|O_H0h}9CnfWjnh!eUuiQCFfmuY4;_!A6{)1xOCwfnawPfVHa`MMz zqczJ!B1xJavoA%EB8;zMKuq#dZ<^mMCE}iso}6gXjIyWdXyqZIu+}lsp1IgOr1ZqL zM8;SCLBqWLdP~2Hl}-u)ziMT@;_Hr6rB2;QqVvLkqSI38*H%%H!kK_I=qN{Du3dUl zJ_-ePSL6vd=#sCD9icY9ijM*AzdKMv!kx`rBqm)J$CCMk<<`A7x?Ufw)o$=d#`Zgs zWgxJZ10rUqMOWqhuVKSYDu_<7o`icPI?Z&%{tlQt8wGvGyRg`EuA}+SmE( zCG%5uID|Cv)(c*Lx~41r2^2OC;N?kmKrS!c-j;-M@b5LX<$I}MC|nvi!NwK79k0W; zWsm0jP^xO~(+T}U76s#S=|?bJfR>%>bY*#8k!Za0n#!m)jks%E`*anESRQ}_D{yp4 z3YHmb)>L;584|Bp*p`eb0m@C`8(j z`pkn-#$c8}Y^NiyQChB8j>2mhuutIb&+t!1NtFc~o(2Cq*K?Lkl>PKKPb!X;sq;K#FQvVg*yE#IaYD$FIGubknj`C*$GY4 zO}&C%x4PU}8laaQ(~1)s^1ElICxs}>t0Tu< zf#d8y|Ak2vJoe^A4Jc*-t8cQ(S%q+%EgxXpZrgJc3NQ4+cJ6VVZTJM~ou$-@q?hp~ zVA7#S_*Yj0#p=T@!BL)eWmv2t;^ct5=M23JE;=4iS{d#6U^=Qi)3FLqV){AD5T;%m zGtMpVh}BC)M8e5BbMRas8R1v`n_cxYKr2i(3(gyjOo}-x{-(7CCPt*WY8KK)zIxr? zl5}>LW)f_%6N^j60HA|)PCU{6@TaFj7YF&2qb0;cHP6lnfMe$;fwkKslui+AZEn3P zvs=nlg99(=HmUD{Pz-MwQp5h=KvP2v#aY6{@0zKvLhpRDB`AD!KU*lkphipEBGX63XNWM&swcF}w7y5qM4x z#QotAkVlS^80IQz$Tl|6d8`f|x#{dgLL{sbQMP05C8Jv;egEa-);n*rnQa~!XO9S^Of)S#L*$%|0UP5aQGDPY9fi}sXQnf^wMl#s z1SiDFSB#cx6@~!eCg*)ihdd6!D8m~*wZtHZ`F$r|nZ+0VOIf`p>8RFrmr4MPqDvNn zNuo^3xfE1f6i^qgPe6b6sRzC`hNjC{062vAKvYi7AA^A(De&)>m}IS%id+kW2l(qR zu@3v^{Ls=fB190;x}C%6I%-W;)~4doA@aJKVe4oze3O1ekFxTljE73tDt?KhKPz0A z8JBqtV=0G|tWa+YbBgd=@@A{i@|Y<1Ebt>Tz0eg#o<8z~IJSUeeI>6gAZt(S%vwwZ zXVpHnlb#b)?3$8~0%fL7l#e*oMwWc%qq^&wVL?$uv>m#ov)<=LqHG><48YUm~63@wuHa<^CSxQ_lsDEUn5PFX@+-OqOqbNJZhvPJ+9 zFX7nSU-A^^x809Ow>3&<+SsEp;v8G z_T$Uz zUdaN<_iS2rAC5vN*}OyfJ;;ACfk|GTs&e=CS>HqPrX(;EO}D2>wy268@IE&_p2!@B z=sKo}oyx-Wi)=NUnm{E`ms%5&Y4S@&Yc#bsGiiX&%G8G5 zBJ?qi=!&E#tMcB3`)=o9K($Vp?j6UPBy zIZox+XZ1Nkfb71nV7zLEE|l}mkT8X7P|OBh>mt<(H{su@q|Pm0SfXu-#`g|w@p#M8 zi10c!JG!KxYV}&m--)bq39RMHA6y~FWlE^cS!oH2Cl!OsTxgYks7)NXdH*F^WnT-p zPLlRAd@wjhFN>_OP>e^GqKbpBIY_amae7jp9HGmLqjeq=Yi=0kRQ(YkJKK2h2FPx> z$-pbrZF&_aDdcWh+ zIs`$&PQ7VhRJUAr)Gy4srofV+14OJHy=a!anJ2f&ITGR4ZM#zV51$|m4qWvNyt|T> zT44_^*V2@2@C9sA0rMDKaj(>T0}+yFWuM%0-+*7}i=NBo>!di=5A0+B?mn6m#$S>5 zJKp<*Fiy683~&=R{$GPFs=E+mQbm~UnbpKI!lc{`OSf)CXxf9HP9fYy#i)29`T7>> zLSEJALTO0dkjMf{1%Ec4kO-9UBE zaDBT7aN4E+-&~@6tyx4hELBn^XDkV4;aG`-URT^hy!y3;Nt9Yp#@dwZyKp{{7LOga z01RY{I(!Lq7R^7m2b?tGQxn>JtS`}!M@Fp+s!lUz`~~pNeV1UR`By6$uR4!e6pY)p zg-Um1d+#=J}x$cUD*cYF?wfS<3O4v6tk`RLskumVhvJT@Fv+-br)rkUWMm&^cPSs-WlDyd{=I;ZgA_vLB0=i;QzcQ3aeh@5sn*g znv!|zr8iz4HfygpejKck~c2)ddZ=D$^Tsx&96uRqDK`+$WrfolW zAxFh*o{t&ggVV@_8MWK_39EkR>`4L^GOa5jLqJLFq(n+AM)sr|(Mb3Yw_0{2B_2A0Kdop?HVm~sq zF+A=fTXqc`6tJ(pe5I;9^zJGWK46N%OS-sjd6yUHo@SOCU1j`^O|@Xost&l{T|wf- z49h4zSw!9}mSAd(C{D9v*TU_6xu)|ZwnCY8bAt}+s#%%Q=7$rRI)>8Kx$6>`y%uHt z&VE>Wga5-qzxt+{#?!?81&-Rqti&J_XJl?4Uz%GKYS~#Lrhs27b&R!l|u_m8-)nj(C>-f*d zfQ1yBe7*W0;T}Q3F4Zm$|5Hm)=6?T$9?DznmlvFsz)%1o6$l@F7*azH!ez6&1Z zzwvMm!M<3dT5?Lxa5A5HL6}MmUmO|^#y2f=OfA|g)_$x zvl|9MG}_YRsy`?i3wVTFx|(P?NR?eNM)t`-`vjUTVx5y}14tA(^hC(4K6s@Cm+Dl2 zs#nbtAm~CycaDu>H|02mp%&gnK)*vdUP%3vaZ>=zN#&5weFrR2M{#U?NfMOv=Yh=q zAG)Tu`gmxx>r_ZzE&C?!Ye9I1V}!)VIYV{x)+klhWZ~$jyPZ2jb4UsM)lB+W+JUr2 z10rtJ$o3-8V!|0rW2DY8?+5d%mD7R4Tql`l&Sl(Z74oUjtM7X04;?D9Xtg^M3}Fgb*#eSol1*K~`t?>`nUt>p6TQm@P4 z{7XUS93NGc*q?nfN@g%fv>n!6{gy76^ntosk;arsSzbr}^T~DnFbe8HTQW_6$z!1+ znbwEkzUsTHz2xP=ef@${C)y64y|KIS)&EDU310>H)(JLuW%OO#YB6^#`O&W;Dd<%2 zIW!Ojt7~}`%aJl!L%&}VY{fPDoGP4Z9zh=EoViH=CIxuI^L;=cPSTdMF~Di7<&2)x z!5_5@zut8`MVdz3PF6{ezR1m;2*Q1?Ls$>QUf~J7GAmZBP?FssVB+kzN%$4SOF2%&v=< zml6?=JuCf_pu+>xs9(^b&M-<=Fk|4=C8YAcw(DX#2P*6_0?%m*HTmsKQO%!SoC)tobF{@i(5^5OnVk+Q zF{u4-bKWqVsfF4?-3;OhG=AW$s7t-}zrQpg@ zh9iv20Ka%Xqh@+GxWS1{>3GcA7LG;f%|%7DAr)=y>& z@ZHN=&a+#3k=>Uvr6MiWRS+g96_TC(eTCrsTxEu8kFjmL^S%51-K@|Kf)y#oh>^X?9%7cimyQ490}t`8{d%&Q?}8EQCnhYSKIgD8=t~K zq9nJ6F%(rOHZ*ii*cUd*hsyTbg=x(Hs>Erc8ss$E7GY<60`;{V@@33akoduP zRjtW!OXk2od;3Yi54AvUE{(u}3{rlz>{MX8>X*D@#7dpZJV?iUM?YWt7e9*Z>4?PZ zJlrtlHS2bh5i)2B4&S?Xf^Buyx~0+<5HsoZgC-cx*8Byt%?s4PSf6dKwO-P^rJVfz z*Q3}vJojfI=+9X;LQ%{Lu!g1_)7Zp_8;2I$eUs>#V}nj{sLGPEjP_m&T4h68lZ6Hs z^s-23Tl-+X>0ehEg}6nNV%Tlnt#6&d7sw4k&cTAF7R#&VPX+*_z=G-E<#V}u@h8oR zBZu8t_*VsWdv}AbeXovtAu5g&X*A-UMLWtcPGKk9BiX{si|o5Fimw_!=CF;?k{N`E zKEsN)BW8+zXty)1&Y!?b$A^-)Umj=lOz|KCFMi%iT!iVhCBF@QhoQW25%m+^0HRDE z@k97lmIJCU*!U}bHD{o9uboD$Yz?7uQh?ei_s@ubzy1)^5!mWi=G6%)6+~R4 zJu?(8#s(A>1!Gpy#Ja5IlW79IB&l|J`CUTYwaWkU%D5wd67DsNL~C`u-?Ba8>77li zvnXE=`F}!Ou{opjaPve!FI>I1*}F%;j6&}68}NF zFw8`OU+(Vi2G`G*Y3#&x1Op8RDySLG9ryB>BA*f>d!Q1mM~#*E@pyYMp4RYQdyc)ZR6{|s2Hxv!tK>Bs&7b7Ak zT||<|)>YzD@?=CK=)x5m35eLSNgxCIRQV)9xoN=he!rCMhGoED6H!&Ru-vH2s~TS} zZ4g1^Zi}g&oarCcH%seJMJ`TZ<)krvnbjfcOI+#fy=xAh7UAlD32b~lSntuQp&4W7yFR_Q8r@G7pjD~AH$PZn^{ReF zhRQRGw+XG}=DeY!SHiOW%(avyt~741Bq>X*;IKzx{(Bv>`tLSR-#vfZRbG8>hN}6) z4cjtDryI>D!QL62J80`UgRw4**$nsxjXD2`>X*}(sa?uEHKHf*$1%N(Q~f|6Q&*LHDNYXjEd zovJ3q@@OrQ|Cmp+UtGKv!Xy?GJY{EKPGQ*((63gsrGduL`+8XDH39kC)PEj!9Mtt#dj*oKJ=iWhkJ@rRY^L@SO z5JJ1Jw2g229gtr8?ewc&oSx!k6n;ZK4YK(-cWlc1QGxt{FO|1YJMQG9L#sABZca7w zgqGYIiPr3btyw+}G2J^sDnU4jsQds&Jp57mzgHF8oO)MFE-)x%V!tt7BJG@`ti^!4 zt|T{2*wq8eWUwoJ!wcAiM2LwQ90o`~P#6Ju+e`Op95`ApVotGEKMg80?wsxaQj5|#QdK~#)GKlN;QhF<(?^$xn%+v|22hL%1^g@5l^O5OVj=E8;& zyz-_Jx=Qdo7~@$Mt94zAVmKH>8b|JRO?Cr^=I{t`Z{5zA$?LTj_?1}-nE z5P;lQQ_ukrBJbTbQR7Kb;n;_{HQQi!H0higN{{o;)&;&R(2;?AP5-@45Hxf|nN~mh zrpR5Ld%jj4?|wCjUm9QGC?gu}VsPt-wd;dqmFhlDjHwudalajma3rk@wu%4n(QV&c z+P!wFJ2*uQ-gFqeCzW#> z&CeYHSRS*+7DV>PeYWpnK@D4jy-5@PTdurWBKlL+Nsw09{oGHn`~B>k9eT@|6@pH| z(l@q_5hS>k;yU{_xN4F&IdIqqu)*D?8QeBeCL^nbF(&AKP7Ue&EbpwF1Boxe2Sl)U z$-%|7HUR5(G-5jh zhU3GKl&;_kaZ!fC)nOpR+mQLw0fDlg$&5zg^cvfztFPthbYi)Gmyol{EPNcqqYriS z2V41jCi`askM!yIF2mGf(>sp`F@<#d0eBB6>FX;4D}-0$Q+VNtf_?jyQro{0mF#Y&A z*B0M=ggOQ%!?a{ucO6!c5%@fuUd0c%jA^BcKP(^jIVNsgt5(JlAl_yT@E`Kpox-v) z2_$5F!Tm=~EfvXYjq(JN`D`)r*!@q_Ag6JF;D)T1*o}mu4xs5Rpn>f4Hk!ynevs1G zeHlKlja?lpp;fIuOZ?Zm{xQ0W+2<_5p-OhTsI1i^8HBMo&sF}?O@G8p1Qw$hsmk8n5yqcg*^Bq^$VGySTfwI(f2z1y8hroxqsa2(c({Vgu|^%aUX|sktsSR>vRR?uKC_E0T_Db5 z4kF^S+j<%Rn!5Ia^0m}BwDU{;E0_N{xU4Xtzgss}JF##{eZl79rF80w8Gm9~Kn?@c zahQMHuLSy#=yfWb;Y<05!r+n|OhJ7}YT#QY%5^Zvjk&g#B3)-%#04i~J{?0!&#fnZ zZeX$qYu5V;zWiF;i?7jmkJoKe8BW@_nnAKr z3>y5H_gv1$XV2ST6{{@P7Bw@(K3#g~lzh(g2nrx!o=r=v2tF*&uv6?8G{J(x3`&tP zm~gtyd>8Hkg5afAF|v{kZeBdmmfWO#Tx=rMx=}wzci0lA?jw_bGh%;(mer`~hYm|LI~NSaY1xh`zryAWBq3J0Lx ze1RWIZ78fxjHU&S(>wcyzuXY#gh(f8*`3kkGOg-@g)csoO6*b0o_cW6RnGGHV>1c0 zf{WI_+WIB2w1D~dOTLept2M~8M~93%wX1ObK!iv}o%^!ttIWGyl^oH^E`g`?FLnht z;uuf`4FV#qL+OXs5zpmz)+8@S!oi)_K3_OPufBf!_l|! zhg+)oFyEj;Q+9WQ)o{T`I^=6Tv=`im1Zv2tZ^}zS;CJ$vDA7XCvZToh=W`oJiu=6z z6F~wMv-x&}6Oir24Jt@ABZ=EUZX!vc_3Sk)mQj&A+D-6g2)Y9UyPj*Zz|>e(8$~Y_ zJF6n_r6renu$kD2YGbTHLVf}vvp$%ZlL6eZ%|dVDxb7Pb8gIx#n`=R;8BZmoX(DZw zoK3&Hxb~-H-)QCQQX&Z4(Xx*C>?tvvO=C5NdSvq&F^3v!3gcHlrIj6I?R7Sj0lhsh zC$)dZMrTO!95+DL_bXmdHG0j8)E+VDD`1?n0kxmIifJ!Q7`&3N2!?C5|q!dSTxi5_sE*jEs8#YnqO% zt+lnIpBe{S-dCbP!8yEl94tUfp#MO7-Inm5NVy&33=wvP3~iS}qlE+7*Vg7Iwx}z6 zoPU(i6&W3YzJZl8li20;Z0D`f{8AJ%e$Tz5s!9jVx-Y&dEWp@telViqj7zTb&VL0u$q{sNs*v>BszI1ZDVr4UmW&iYw8w zXACgxO=&jFzY{YO!Flvrud)of8z>-$7OiObg#xXw@D2SpP>ZG-2DgRH8J;#`Se!0V5g_))g8?9VJC|UdARQAsF%&OQk0S+>CN}H{!g3bK zK4O%g-ueSLUp5&KY;G8O=o|y7R209BicGZZzDTdY8fm`wXhXl)jw!-%YQbk@@rFUp z)tKiFA@(Vl9EJ-xTj&Rg+;Pauw^9mH-rCN!XwR`>*NkWW%D{t*N;MV%|M%L|vmCnMJfZ zZbyY$i>+?#&(wi5FKc@uTdaw6MZ(AJyjH^sTp6Xj4QWR>a=hPZ3>!iLxyUZKc&XdgIvQ^{;p1+Tn@)HN%*l{elYemz{!8y|o%+ymc3 z6o9_3O4$U!Ode;(fIqZAu5Is911ND<5-o)^?oL9X2cdkZ+c+0-&8x1Zmf%ml%_JSZ z3E>L{jC$1RgweUi#1yIIE1C>PV3D%#)gy8!w5-ht<~qPb#se{&W0@~PaFf8$t3=|6 zCoYd#!Sp8oF(nm=ob)xF)cvKFr-YztNhy#BiRS ztB8D`;r0wVb3$U?7IHFpKnZ2vMII5p)_I7$7XWUoNDoVwi?a-O*ZAAkfKYli#7R%)|qT z%=U-~<(d2rP20$;{~%PFWICBnwLQD@MaK$_uxt-3Wv19^ok~iCRlj}TP{{N!ZSQ?m z=#R5`yT{+zk5>Jo^G@m+V+&%dBALoU4v6&{%+Wy~_>%gnYz0B2Nf`%=fc z{t!wgvhYhO$gy^t?l70OHLy$4d#amRCNsE4i+j%eBf+v$?1wN6}%H1~DXz zQwmL9@vn&r2M;aVl}CQ!U*O%$vghCI%mj^J5T>Jr4FD!hpgoEU%;;ABd-A~(SieuZ zU&LaWK}@jL25aD^HdpMY5nMe<)B58*>x9qx?LBuzh-PMxZgeww!EfOFlRBj;3FLmj z4vW~5{Y__`zir`2E?s%DzNEnEj$Pg@h;ibODevyhAdQ`s1FxW6}p?0HzJUZ!Y3b|a%#nl z6J_L$BThtcyXtN(+x7!7L$jPk4D#^9h+Jby`@nHF7<=oot-Fb8aM$wne%dw+=FLyt z!g@;85$;aw%+FVQn(%Wtw4M!m1C4*+P+G3^zCj)UmhtNOd-v%xkkeo_wyVF*VE`ho z;C9a6ivTqVWZHO1yBmKgP}w6e0sBkU(xZQ;xnk&>>v|5A#m^!#-C`9B;~Y|@97J_L zwmH!85tpJ!Ymvp(K0KzQ(r(|~*sOD7;xLzm=9F#|STSfaxw1qV_4;Oe+Tv1@-hx6J z-W$o-b?rvb#kNL&#%V$QoI-i_13c`1J07ctUJ^!C2SF0-K9S z`*}N%YLNP6mg9y@7R6|WprrIk64-wpq$J}YI0eahvYFJCs5M& zx5mQb3J(jx+Zpc~DW&3DqSBJtvChKem8%0cqg}C9j~{OVjQuETmW8=FsRY-(ycXOU z-!6_dySiyPumnpiGNrip@_%)R&7Yd?V6Ax zp5Nh$_re@fA}&y2eclZyk;*+m!r8di-9$#exA5gislm+DPDLFJc5g!7+xb0LO!-xG z{*z`686EwS>d;M3Pq1<~bMimNnH^U*y*I0r&4<>1(lbI10=Y}SkQnBM=2$8&5K}U; zDA*_HomS?-WY<@>A0d9mU7i#%+B)N$`C^sN zsKJ7y5N4PNFXBc#XcW+%Vph$+=)(njEKLETL2?2Q7d5@W9Bi#VS~dVslTIvtd5p`A zP!!JSzL!W->Vv6#rDAdC?#1#!&>!Q&vxG}U3CWH3t`X_kJ=fidNQ+^cr&>!)kj9;F zk#%H}=Tx*h@c30^W)-$%lvVB*_BfcrocouR?MpUoF@^oqcOZP|q zk?WneJ_Nt&pKM*@u<)|4qaKI={ZLwrER+G;BsMbEa!kMBD~9h@LLCWiQK<1Ixvl=Zluu6mPLzvryw&>t^x zk+1`%rRyzL7BU*;?zRpdiMCXfV4hWHo#%(aDyikt#_9R(&gR`8O}JolZ{7{zb z#Mq@S&J%ag8E|tR@}+BE2f)@q>7R-Y!Oo%Gyv({ab8Q?52A_Rf+n?!PpEU~QvYCLW zDiPQyQrj@={L~fD_~nXvvz`PM4KV-!xk)Ar${Otcz*9jdO!q9dJ z6Z&m_&SOMex0PhwV$!DGG?&+pA_Rx`^Zdcp$;pL!+kvV6DCk0wh}B~P8E);#a!x@z zkp!Z(*xdsyxeQw5!Sa~UG3+H#NQfMe(dDs4dhNzGe{DQvA@8Yf+J|JQHNnA`c>&mR z+CjQLi0z zLG2NuFa2jV9hc-!%^wi2tnwoY6(|@s+>Jt<$29zcc8hsk44-PJ<1-$WPzDT&7pEvS zV7-8ebKcZJQRk1;1{{B*h0Dtj_$4x7M6|_UzF=sW$R_r(p86yT% zCA8K0c!Bh8xH?fvrOEAi*rd~&sdZSP_ol2lOH8nqy*-yRm{UlQ_2CX<^uyP~iSwvXo&;x02M_$ydbs z%MS;p$OGSQg+K(ld`Mb?e<5mKOOm!iBqA+gKnR>YB|#%+wuWABO!7y8mFU{Kv;S}W zeuEeqbJll&Rt^3JcQC@Pr2c$JGy#+ zOo;-}Ye4Uzc@Bow!7@y|3byYYY-vBZCJH#vuQJ`{!&W$N694$8;k+dseSZp2K^1w=@Gd*8u4}#f}jrW~;a0 z5Ha(1H^QO3M8r#ptk%YIvi`eSHi51yUnZ4{T_Z)O90WsqNt3M4uX;c#>wfq7?{J1NS;^wdyn8HXFYD-vL^h87Tvk4%W1J;>4angC4 zx|Lq#`jk?SQzC0GO%GS*%l2+T$*d z1YonwpVK|3#T0Xe4c{0gL@f)psK^j+3~jYamei{^E)IwELd~y~6(^F#EJ~5rvfp&7 z@m1^-y>VY+lYK+y?mDOnn;IJom1p~SEQ^Ve+K?Xt!nj{%4X|un)Ol?tgHNsGH&;&% z%Ju*p83w;B*75?cJghU%m}-2UaJM(BHi7OZLZ6))-o{{{T#sv&gm{Yha18VlGLN>_ z+$9)-TwIi2Bn~!@YW+>WN+7K96Uht!gP08O;}nTM)H~kLpwnYhRcwH_OvS7j(ui|4 z--H;9-u^2~N(U6uLm?`-ZYbXM@^W|P!Mwot1|s``!d0rNv7&0f=`g)1=iXtr^z|X5 zHytVKm=h5aXlL_b?j_%kbfZazd+=An^@3-kX%G5#_g0ssd_R&P#!#4hGr+Fnt)c0u zwyE&^pkmF|3Ug zCEV-#+zp>f6w$Lk5&;QDD-S216-4p zCi@@2HPWfr+G_fLX23j2OrI%bfd4^v2*FGK_pDxv}iZg$Dt5Eq0Q>G`q(U4 zwpvHPrz7~Z>`g*fNeCSB;a3g!9vRNI!6;D05QkhE0R|?kszJ z=a72!wL7kf&3XjzUp)4UaXIZ8vY(xBxQ;!pH+?b8BL40C!&W*JVHL~Zt*O)uRX-DK z-O1ZW{ma|^|Izg*<(f(3nH%BlsUM|kVz{DqwF4>$+H|UhgYONwVTH2&0hg|`*bQ!3R_dqo1aMU&9w3VIC?y) zA!t_Y`6)YUpB|}KIE=7Ra{}{c+B5!L`*}8cpY;Zp7DvnfPWX9_DKl3kn+mA(d-um} zNLf6zVEbiOnPZ<7Id_s+q(-7y&;5`ZF)O4%cYlj(!yF>mcax|~OPI7WQ5IJp)+8J7 zQsnHi4ibk;AW-54@rccKi*e#zGYn-wIkmsAxfNj;%Z+m36|2_d$1Pq<4UVNxnZBO- zFa}r|pe`E;Do|ryiaVa)13i^@8x{X7eVo3F;2-pl^0tbi4vePlmZ&Nx6@kKLqM!)fAG(YD6<1?Ckp_m|9ir%%b)Eheg;)F`G=iGq8VbQkWrVRSGevN|wu~ zY>=X8#refW6$pTM7Ps&?TK1Moy$jL;Qtb^#X@|C3x<<#_YF;FQT_p zD>x>6aE<_|%)PSlSU@>zkqHw47s(B(hKsL5gzHgn`kl~%QN0aj19F?b(hMw`XT`?( z#jvo%O`s$?k^?DVyFu4ObFh|a;B`SLb@QHTiAX(xyHX1MNuihrLnCbRe@?935S9q& zhmTiU9$ek7Q7(JDC7k9<@N{j5RCg@J4iZZTX%UU9kxS!r=4(gHye-S=)cFS- z;&`0=tBwP2N{7cTyVEvirS%wLckwd?Ahmwn96^TQyz6GD%!qVf@=hT$mR{3Q`jq}m zQk(i(mYz^8i9AB%D-LfK)UtEq5c&7-@RF~=&|ev@q^35@ITN-U=P)9^$$MJ=rP+EE zvV|(~R%t!Rw>c+6NJigXI*P-w?z5M)FX?K|9&EQBR-41PYXirA=|MFsW@Hv}wo`$j zC3hUdBbRlWGLiqpJ;{cAMRTyFs3Jy6IL+A`_872e95L%45;k{0dDt}tw|4JGPQqRN z40JkNKF^}jdn?)WsepaT%M8Hx45|aSEKVxnwXi#o14a^D(}b#J-b^T;XW4DL@wzb! zXo!R)SfPl>rm5a7#d3Wd;av#tWjiZw`BKUuzf>Ol0BP>4vYCNcs!ek1J$9)NvbI*O zHD=0bUE&aRDx2WRooG(nykVINE?{pW!UXHn1ko2|_b2r~Vk-y>CcVoZ)4?<>P1DTL zv$|HBm1j&&N!EViV3|or`uQMEY-1Xtzha+>LBPW~bgJBsGIi_S+NYiOB zBb)}I^qMW7O}yOX`OI(?77tF)xjmsFt?w+k>jaej z!lT7v@vR~}kAr)MNdJ6*Xl?poI|$DsIqgL!qtC58XxGG+Sic!?+|bK& zb3wlMY_4|zW?pfD+Z40%umW$vClZviL=vlN%`eJNoS&G zj!v%^tDcQ&EbuW2RK@fXMw{e=*Ah4pbKC@`Ul-JULe%YSruk;Z9@;q_F_y2xRK6B-V$9G}h6ZtW6(5vPWNKJ&>!dgdQdT z|D{ixDNPw)=W?SbaWZ$vF!IBh36{_?*n1l@LDb|&_AU>Nwd67?w!jg4Cjas~#J|n1 zJg?tNANy*NeQ@f(2$3e-sQ8A$5_c#9_rkQPUgLfjuGn?*sevlD+tVN6y;d&K zI-0`bt)r1|OStfkVKdC$ydQiE%Q^`A*^}r=4PXy76YYs=?(fM$&f+$_f}~&4WNp0c ymiBq}_GyjLP@01f0001|bJ+oICd?-Q0s6)WfWSyv-gSnt#Ao{g000001X)_eQw|;g literal 140144 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 Y@ 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

GHLKrie#r;I4>FR;K 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

fV>B3}2x)_D*szP>XT&H5VHcS#ft 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 Czg|87 diff --git a/backend/vector.c b/backend/vector.c index 7796cfa2..319c3e95 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -921,7 +921,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ } /* Separator binding for stacked barcodes */ - if ((symbol->output_options & BARCODE_BIND) && (symbol->rows > 1) && is_stackable(symbol->symbology)) { + if ((symbol->output_options & BARCODE_BIND) && symbol->rows > 1 && is_bindable(symbol->symbology)) { float sep_xoffset = xoffset; float sep_width = symbol->width; float sep_height = 1.0f, sep_yoffset, sep_half_height; diff --git a/backend/zint.h b/backend/zint.h index 32dc671f..2df11453 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -33,7 +33,10 @@ /* * Version: 2.15.0.9 (dev) (see "zintconfig.h") * - * For documentation, see "../docs/manual.txt" or "../docs/manual.html" or online at + * For documentation, see "../docs/manual.txt" or "../docs/manual.html" or the + * PDF manual for 2.15.0 at + * https://sourceforge.net/projects/zint/files/zint/2.15.0/manual.pdf/download + * or online at * https://zint.org.uk/manual/ */ @@ -366,6 +369,7 @@ extern "C" { #define ZINT_CAP_MASK 0x0800 /* Is mask selectable? */ #define ZINT_CAP_STRUCTAPP 0x1000 /* Supports Structured Append? */ #define ZINT_CAP_COMPLIANT_HEIGHT 0x2000 /* Has compliant height? */ +#define ZINT_CAP_BINDABLE 0x4000 /* Can set row separators? */ /* The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code */ #define ZINT_MAX_DATA_LEN 17400 diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp index ff7f788f..1cab7c5b 100644 --- a/backend_qt/qzint.cpp +++ b/backend_qt/qzint.cpp @@ -894,6 +894,10 @@ namespace Zint { return ZBarcode_Cap(symbology ? symbology : m_symbol, ZINT_CAP_COMPLIANT_HEIGHT); } + bool QZint::isBindable(int symbology) const { + return ZBarcode_Cap(symbology ? symbology : m_symbol, ZINT_CAP_BINDABLE); + } + /* Whether takes GS1 AI-delimited data */ bool QZint::takesGS1AIData(int symbology) const { if (symbology == 0) { diff --git a/backend_qt/qzint.h b/backend_qt/qzint.h index b3230bad..8001624f 100644 --- a/backend_qt/qzint.h +++ b/backend_qt/qzint.h @@ -268,6 +268,7 @@ public: bool hasMask(int symbology = 0) const; bool supportsStructApp(int symbology = 0) const; bool hasCompliantHeight(int symbology = 0) const; + bool isBindable(int symbology = 0) const; /* Whether takes GS1 AI-delimited data */ bool takesGS1AIData(int symbology = 0) const; diff --git a/backend_qt/tests/test_qzint.cpp b/backend_qt/tests/test_qzint.cpp index 9da3689d..95a2a54d 100644 --- a/backend_qt/tests/test_qzint.cpp +++ b/backend_qt/tests/test_qzint.cpp @@ -384,12 +384,12 @@ private slots: QTest::addColumn("cap_flag"); QTest::newRow("BARCODE_CODE11") << BARCODE_CODE11 - << (ZINT_CAP_HRT | ZINT_CAP_STACKABLE); + << (ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_BINDABLE); QTest::newRow("BARCODE_CODE128") << BARCODE_CODE128 - << (ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_READER_INIT); + << (ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_READER_INIT | ZINT_CAP_BINDABLE); QTest::newRow("BARCODE_EANX") << BARCODE_EANX << (ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_QUIET_ZONES - | ZINT_CAP_COMPLIANT_HEIGHT); + | ZINT_CAP_COMPLIANT_HEIGHT | ZINT_CAP_BINDABLE); QTest::newRow("BARCODE_EANX_CC") << BARCODE_EANX_CC << (ZINT_CAP_HRT | ZINT_CAP_EXTENDABLE | ZINT_CAP_COMPOSITE | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT); @@ -420,6 +420,7 @@ private slots: QCOMPARE(bc.hasMask(), (cap_flag & ZINT_CAP_MASK) != 0); QCOMPARE(bc.supportsStructApp(), (cap_flag & ZINT_CAP_STRUCTAPP) != 0); QCOMPARE(bc.hasCompliantHeight(), (cap_flag & ZINT_CAP_COMPLIANT_HEIGHT) != 0); + QCOMPARE(bc.isBindable(), (cap_flag & ZINT_CAP_BINDABLE) != 0); } void renderTest_data() diff --git a/docs/manual.html b/docs/manual.html index 383b9b6a..2830fb7d 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -333,7 +333,7 @@

Zint Barcode Generator and Zint Barcode Studio User Manual

Version 2.15.0.9

-

March 2025

+

April 2025