CODABLOCKF and CODE128 fixes; row separator height option_3; #191

This commit is contained in:
gitlost 2020-05-16 10:22:33 +01:00
parent 23bbe81cb5
commit 8dcd09406c
19 changed files with 1743 additions and 511 deletions

View File

@ -37,8 +37,10 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#include <malloc.h> #include <malloc.h>
#endif #endif
#include <assert.h>
#include "common.h" #include "common.h"
#include "gs1.h"
INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length);
#define uchar unsigned char #define uchar unsigned char
@ -50,6 +52,7 @@
#define CShift 16 #define CShift 16
#define CFill 32 #define CFill 32
#define CodeFNC1 64 #define CodeFNC1 64
#define CodeFNC4 128
#define ZTNum (CodeA+CodeB+CodeC) #define ZTNum (CodeA+CodeB+CodeC)
#define ZTFNC1 (CodeA+CodeB+CodeC+CodeFNC1) #define ZTFNC1 (CodeA+CodeB+CodeC+CodeFNC1)
@ -90,7 +93,7 @@ typedef struct sCharacterSetTable
} CharacterSetTable; } CharacterSetTable;
/* Find the possible Code-128 Character sets for a character /* Find the possible Code-128 Character sets for a character
* The result is an or of CodeA,CodeB,CodeC,CodeFNC1 in dependency of the * The result is an or of CodeA, CodeB, CodeC, CodeFNC1, CodeFNC4 depending on the
* possible Code 128 character sets. * possible Code 128 character sets.
*/ */
static int GetPossibleCharacterSet(unsigned char C) static int GetPossibleCharacterSet(unsigned char C)
@ -101,14 +104,16 @@ static int GetPossibleCharacterSet(unsigned char C)
return ZTNum; /* ZTNum=CodeA+CodeB+CodeC */ return ZTNum; /* ZTNum=CodeA+CodeB+CodeC */
if (C==aFNC1) if (C==aFNC1)
return ZTFNC1; /* ZTFNC1=CodeA+CodeB+CodeC+CodeFNC1 */ return ZTFNC1; /* ZTFNC1=CodeA+CodeB+CodeC+CodeFNC1 */
if (C==aFNC4)
return (CodeA | CodeB | CodeFNC4);
if (C>='\x60' && C<='\x7f') /* 60 to 127 */ if (C>='\x60' && C<='\x7f') /* 60 to 127 */
return CodeB; return CodeB;
return CodeA+CodeB; return CodeA+CodeB;
} }
/* Create a Table with the following information for each Data character: /* Create a Table with the following information for each Data character:
* int CharacterSet is an or of CodeA,CodeB,CodeC,CodeFNC1, in * int CharacterSet is an or of CodeA, CodeB, CodeC, CodeFNC1, CodeFNC4,
* dependency which character set is applicable. * depending on which character set is applicable.
* (Result of GetPossibleCharacterSet) * (Result of GetPossibleCharacterSet)
* int AFollowing,BFollowing The number of source characters you still may encode * int AFollowing,BFollowing The number of source characters you still may encode
* in this character set. * in this character set.
@ -194,7 +199,6 @@ static int RemainingDigits(CharacterSetTable *T, int charCur,int emptyColumns)
/* Find the Character distribution at a given column count. /* Find the Character distribution at a given column count.
* If too many rows (>44) are requested the columns are extended. * If too many rows (>44) are requested the columns are extended.
* A one-liner may be choosen if shorter.
* Parameters : * Parameters :
* T Pointer on the Characters which fit in the row * T Pointer on the Characters which fit in the row
* If a different count is calculated it is corrected * If a different count is calculated it is corrected
@ -215,24 +219,20 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
int emptyColumns2; /* Alternative emptyColumns to compare */ int emptyColumns2; /* Alternative emptyColumns to compare */
int CPaires; /* Number of digit pairs which may fit in the line */ int CPaires; /* Number of digit pairs which may fit in the line */
int characterSetCur; /* Current Character Set */ int characterSetCur; /* Current Character Set */
int isFNC4; /* Set if current character FNC4 */
useColumns=*pUseColumns; useColumns=*pUseColumns;
if (useColumns<3)
useColumns=3;
/* >>> Loop until rowsCur<44 */ /* >>> Loop until rowsCur <= 44 */
do { do {
int charCur=0; int charCur=0;
int fOneLiner=1; /* First try one-Liner */
memset(pSet,0,dataLength*sizeof(int)); memset(pSet,0,dataLength*sizeof(int));
rowsCur=0; rowsCur=0;
/* >>> Line and OneLiner-try Loop */ /* >>> Line Loop */
do{ do{
/* >> Start Character */ /* >> Start Character */
emptyColumns=useColumns; /* Remained place in Line */ emptyColumns=useColumns; /* Remained place in Line */
if (fOneLiner)
emptyColumns+=2;
/* >>Choose in Set A or B */ /* >>Choose in Set A or B */
/* (C is changed as an option later on) */ /* (C is changed as an option later on) */
@ -262,7 +262,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
/* Start odd is not better */ /* Start odd is not better */
/* We start in C */ /* We start in C */
pSet[charCur]=characterSetCur=CodeC; pSet[charCur]=characterSetCur=CodeC;
/* Inkrement charCur */ /* Increment charCur */
if (T[charCur].CharacterSet!=ZTFNC1) if (T[charCur].CharacterSet!=ZTFNC1)
++charCur; /* 2 Num.Digits */ ++charCur; /* 2 Num.Digits */
} }
@ -273,6 +273,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
/* >> Following characters */ /* >> Following characters */
while(emptyColumns>0 && charCur<dataLength) while(emptyColumns>0 && charCur<dataLength)
{ {
isFNC4 = (T[charCur].CharacterSet & CodeFNC4);
switch(characterSetCur){ switch(characterSetCur){
case CodeA: case CodeA:
case CodeB: case CodeB:
@ -292,18 +293,23 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
emptyColumns-=2; /* <SwitchC>12 */ emptyColumns-=2; /* <SwitchC>12 */
} else if (characterSetCur==CodeA) } else if (characterSetCur==CodeA)
{ {
if(T[charCur].AFollowing==0) if (T[charCur].AFollowing == 0 || (isFNC4 && T[charCur].AFollowing == 1))
{ {
/* Must change to B */ /* Must change to B */
if (emptyColumns==1) if (emptyColumns == 1 || (isFNC4 && emptyColumns == 2))
{ {
/* Can't switch: */ /* Can't switch: */
pSet[charCur-1]|=CEnd+CFill; pSet[charCur-1]|=CEnd+CFill;
emptyColumns=0; emptyColumns=0;
}else{ }else{
/* <Shift> or <switchB>? */ /* <Shift> or <switchB>? */
if (T[charCur].BFollowing==1) if (T[charCur].BFollowing == 1 || (isFNC4 && T[charCur].BFollowing == 2))
{ {
/* Note using order "FNC4 shift char" (same as CODE128) not "shift FNC4 char" as given in Table B.1 and Table B.2 */
if (isFNC4) { /* So skip FNC4 and shift value instead */
--emptyColumns;
++charCur;
}
pSet[charCur]|=CShift; pSet[charCur]|=CShift;
} else { } else {
pSet[charCur]|=CodeB; pSet[charCur]|=CodeB;
@ -312,23 +318,32 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
emptyColumns-=2; emptyColumns-=2;
++charCur; ++charCur;
} }
} else if (isFNC4 && emptyColumns == 1) {
/* Can't fit extended ASCII on same line */
pSet[charCur-1]|=CEnd+CFill;
emptyColumns=0;
}else{ }else{
--emptyColumns; --emptyColumns;
++charCur; ++charCur;
} }
} else { /* Last possibility : CodeB */ } else { /* Last possibility : CodeB */
if(T[charCur].BFollowing==0) if (T[charCur].BFollowing == 0 || (isFNC4 && T[charCur].BFollowing == 1))
{ {
/* Must change to A */ /* Must change to A */
if (emptyColumns==1) if (emptyColumns == 1 || (isFNC4 && emptyColumns == 2))
{ {
/* Can't switch: */ /* Can't switch: */
pSet[charCur-1]|=CEnd+CFill; pSet[charCur-1]|=CEnd+CFill;
emptyColumns=0; emptyColumns=0;
} else { } else {
/* <Shift> or <switchA>? */ /* <Shift> or <switchA>? */
if (T[charCur].AFollowing==1) if (T[charCur].AFollowing == 1 || (isFNC4 && T[charCur].AFollowing == 2))
{ {
/* Note using order "FNC4 shift char" (same as CODE128) not "shift FNC4 char" as given in Table B.1 and Table B.2 */
if (isFNC4) { /* So skip FNC4 and shift value instead */
--emptyColumns;
++charCur;
}
pSet[charCur]|=CShift; pSet[charCur]|=CShift;
} else { } else {
pSet[charCur]|=CodeA; pSet[charCur]|=CodeA;
@ -337,6 +352,10 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
emptyColumns-=2; emptyColumns-=2;
++charCur; ++charCur;
} }
} else if (isFNC4 && emptyColumns == 1) {
/* Can't fit extended ASCII on same line */
pSet[charCur-1]|=CEnd+CFill;
emptyColumns=0;
}else{ }else{
--emptyColumns; --emptyColumns;
++charCur; ++charCur;
@ -371,43 +390,23 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
/* > End of Codeline */ /* > End of Codeline */
pSet[charCur-1]|=CEnd; pSet[charCur-1]|=CEnd;
++rowsCur; ++rowsCur;
if ( fOneLiner)
{
if (charCur<dataLength)
{
/* One line not sufficiant */
fOneLiner=0;
/* Reset and Start again */
charCur=0;
rowsCur=0;
memset(pSet,0,dataLength*sizeof(int));
}else{
/* Calculate real Length of OneLiner */
/* This is -2 BASED !!! */
useColumns-=emptyColumns;
}
}
} while (charCur<dataLength); /* <= Data.Len-1 */ } while (charCur<dataLength); /* <= Data.Len-1 */
/* Place check characters C1,C2 */ /* Allow for check characters K1, K2 */
if (fOneLiner) switch (emptyColumns) {
case 1:
pSet[charCur-1]|=CFill;
/* fall through */
case 0:
++rowsCur;
fillings=useColumns-2+emptyColumns;
break;
case 2:
fillings=0; fillings=0;
else{ break;
switch (emptyColumns) { default:
case 1: pSet[charCur-1]|=CFill;
pSet[charCur-1]|=CFill; fillings=emptyColumns-2;
/* fall through */
case 0:
++rowsCur;
fillings=useColumns-2+emptyColumns;
break;
case 2:
fillings=0;
break;
default:
pSet[charCur-1]|=CFill;
fillings=emptyColumns-2;
}
} }
if (rowsCur>44) { if (rowsCur>44) {
@ -415,6 +414,9 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
if (useColumns > 62) { if (useColumns > 62) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
} else if (rowsCur == 1) {
rowsCur = 2;
fillings += useColumns;
} }
} while(rowsCur>44); } while(rowsCur>44);
if (symbol->debug & ZINT_DEBUG_PRINT) { if (symbol->debug & ZINT_DEBUG_PRINT) {
@ -425,6 +427,7 @@ static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const
*pFillings=fillings; *pFillings=fillings;
return 0; return 0;
} }
/* Find columns if row count is given. /* Find columns if row count is given.
*/ */
static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength, static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength,
@ -432,6 +435,7 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const
{ {
int rowsCur; int rowsCur;
int rowsRequested; /* Number of requested rows */ int rowsRequested; /* Number of requested rows */
int columnsRequested; /* Number of requested columns (if any) */
int backupRows = 0; int backupRows = 0;
int fillings; int fillings;
int backupFillings = 0; int backupFillings = 0;
@ -448,21 +452,21 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const
#endif #endif
rowsRequested=*pRows; rowsRequested=*pRows;
columnsRequested = *pUseColumns >= 4 ? *pUseColumns : 0;
if (symbol->debug & ZINT_DEBUG_PRINT) { if (symbol->debug & ZINT_DEBUG_PRINT) {
fprintf(stderr,"Optimizer : Searching <%i> rows\n",rowsRequested); printf("Optimizer : Searching <%i> rows\n", rowsRequested);
} }
if (rowsRequested==1) if (columnsRequested) {
/* OneLiners are self-calibrating */ testColumns = columnsRequested;
testColumns=32767; } else {
else {
/* First guess */ /* First guess */
testColumns=dataLength/rowsRequested; testColumns=dataLength/rowsRequested;
if (testColumns > 62) if (testColumns > 62)
testColumns = 62; testColumns = 62;
else if (testColumns < 1) else if (testColumns < 4)
testColumns = 1; testColumns = 4;
} }
for (;;) { for (;;) {
@ -475,8 +479,8 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const
return errorCur; return errorCur;
if (rowsCur<=rowsRequested) { if (rowsCur<=rowsRequested) {
/* Less or exactly line number found */ /* Less or exactly line number found */
/* check if column count below already tested or Count = 1*/ /* check if column count below already tested or at smallest/requested */
int fInTestList = (rowsCur == 1 || testColumns == 1); int fInTestList = (rowsCur == 2 || testColumns == 4 || testColumns == columnsRequested);
int posCur; int posCur;
for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) { for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
if ( pTestList[posCur] == testColumns-1 ) if ( pTestList[posCur] == testColumns-1 )
@ -484,21 +488,16 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const
} }
if (fInTestList) { if (fInTestList) {
/* >> Smaller Width already tested /* >> Smaller Width already tested
* if rowsCur=rowsRequested->Exit
* if rowsCur<rowsRequested and fillings>0
* -> New search for rowsRequested:=rowsCur
*/ */
if ( rowsCur == rowsRequested || fillings == 0 || testColumns == 1 ) { if (rowsCur < rowsRequested) {
/* Exit with actual */ fillings += useColumns * (rowsRequested - rowsCur);
*pFillings=fillings; rowsCur = rowsRequested;
*pRows=rowsCur;
*pUseColumns = useColumns;
return 0;
} }
/* Search again for smaller Line number */ /* Exit with actual */
rowsRequested=rowsCur; *pFillings=fillings;
pTestList[0] = testColumns; *pRows=rowsCur;
testListSize = 1; *pUseColumns = useColumns;
return 0;
} }
/* > Test more rows (shorter CDB) */ /* > Test more rows (shorter CDB) */
fBackupOk=(rowsCur==rowsRequested); fBackupOk=(rowsCur==rowsRequested);
@ -508,7 +507,7 @@ static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const
backupRows=rowsCur; backupRows=rowsCur;
--testColumns; --testColumns;
} else { } else {
/* > To many rows */ /* > Too many rows */
int fInTestList = fBackupOk; int fInTestList = fBackupOk;
int posCur; int posCur;
for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) { for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
@ -560,6 +559,7 @@ static void A2C128_A(uchar **ppOutPos,uchar c)
} }
(*ppOutPos)++; (*ppOutPos)++;
} }
/* Output c in Set B /* Output c in Set B
*/ */
static void A2C128_B(uchar **ppOutPos,uchar c) static void A2C128_B(uchar **ppOutPos,uchar c)
@ -577,6 +577,7 @@ static void A2C128_B(uchar **ppOutPos,uchar c)
} }
++(*ppOutPos); ++(*ppOutPos);
} }
/* Output c1, c2 in Set C /* Output c1, c2 in Set C
*/ */
static void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2) static void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2)
@ -590,6 +591,7 @@ static void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2)
} }
(*ppOutPos)++; (*ppOutPos)++;
} }
/* Output a character in Characterset /* Output a character in Characterset
*/ */
static void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2) static void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2)
@ -601,14 +603,13 @@ static void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2)
else else
A2C128_C(ppOutPos,c1,c2); A2C128_C(ppOutPos,c1,c2);
} }
/* XLate Table A of Codablock-F Specification and call output
/* 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, int Sum, int CharacterSet)
{ {
switch (CharacterSet){ switch (CharacterSet){
case CodeA: case CodeA: /* Row # Indicators and Data Check Characters K1/K2 for CodeA and CodeB are the same */
A2C128_A(ppOutPos, (uchar)Sum);
break;
case CodeB: case CodeB:
if (Sum<=31) if (Sum<=31)
A2C128_B(ppOutPos, (uchar)(Sum+96)); A2C128_B(ppOutPos, (uchar)(Sum+96));
@ -644,25 +645,33 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
int *pSet; int *pSet;
uchar * pOutput; uchar * pOutput;
#endif #endif
/* Suppresses clang-analyzer-core.VLASize warning */
assert(length > 0);
/* Parameter check */ /* Parameter check */
/* option1: rows 0: automatic, 1..44 */ /* option1: rows <= 0: automatic, 1..44 */
rows = symbol->option_1; rows = symbol->option_1;
if (rows == 1) {
Error = code_128(symbol, source, length);
if (Error < 5) {
symbol->output_options |= BARCODE_BIND;
if (symbol->border_width == 0) { /* Allow override if non-zero */
symbol->border_width = 2;
}
}
return Error;
}
if (rows > 44) { if (rows > 44) {
strcpy(symbol->errtxt, "410: Rows parameter not in 0..44"); strcpy(symbol->errtxt, "410: Rows parameter not in 0..44");
return ZINT_ERROR_INVALID_OPTION; return ZINT_ERROR_INVALID_OPTION;
} }
/* option_2: (usable data) columns: 0: automatic, 6..66 */ /* option_2: (usable data) columns: <= 0: automatic, 9..67 (min 9 == 4 data, max 67 == 62 data) */
columns = symbol->option_2; columns = symbol->option_2;
if ( ! (columns <= 0 || (columns >= 6 && columns <=66)) ) { if ( ! (columns <= 0 || (columns >= 9 && columns <= 67)) ) {
strcpy(symbol->errtxt, "411: Columns parameter not in 0,6..66"); strcpy(symbol->errtxt, "411: Columns parameter not in 0, 9..67");
return ZINT_ERROR_INVALID_OPTION;
}
/* GS1 not implemented */
if ((symbol->input_mode & 0x07) == GS1_MODE) {
strcpy(symbol->errtxt, "412: GS1 mode not supported");
return ZINT_ERROR_INVALID_OPTION; return ZINT_ERROR_INVALID_OPTION;
} }
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned char data[length*2+1]; unsigned char data[length*2+1];
#else #else
@ -698,19 +707,16 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
/* Find final row and column count */ /* Find final row and column count */
/* nor row nor column count given */ /* nor row nor column count given */
if ( rows <= 0 && columns <= 5 ) { if (rows <= 0 && columns <= 0) {
/* Use Code128 until reasonable size */ /* use 1/1 aspect/ratio Codablock */
if (dataLength < 9) { columns = floor(sqrt(dataLength)) + 5;
rows = 1; if (columns > 67) {
} else { columns = 67;
/* use 1/1 aspect/ratio Codablock */ } else if (columns < 9) {
columns = ((int)floor(sqrt(1.0*dataLength))+5); columns = 9;
if (columns > 64) { }
columns = 64; if (symbol->debug & ZINT_DEBUG_PRINT) {
} printf("Auto column count for %d characters:%d\n", dataLength, columns);
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Auto column count for %d characters:%d\n", dataLength, columns);
}
} }
} }
/* There are 5 Codewords for Organisation Start(2),row(1),CheckSum,Stop */ /* There are 5 Codewords for Organisation Start(2),row(1),CheckSum,Stop */
@ -726,15 +732,14 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
strcpy(symbol->errtxt, "413: Data string too long"); strcpy(symbol->errtxt, "413: Data string too long");
return Error; return Error;
} }
/* Checksum */ /* Suppresses clang-analyzer-core.VLASize warning */
Sum1=Sum2=0; assert(rows >= 2 && useColumns >= 4);
if (rows>1)
{ /* Data Check Characters K1 and K2, Annex F */
int charCur; Sum1 = Sum2 = 0;
for (charCur=0 ; charCur<dataLength ; charCur++) { for (charCur = 0; charCur < (int) length; charCur++) {
Sum1=(Sum1 + (charCur%86+1)*data[charCur])%86; Sum1 = (Sum1 + (charCur + 1) * source[charCur]) % 86; /* Mod as we go along to avoid overflow */
Sum2=(Sum2 + (charCur%86)*data[charCur])%86; Sum2 = (Sum2 + charCur * source[charCur]) % 86;
}
} }
if (symbol->debug & ZINT_DEBUG_PRINT) { /* start a new level of local variables */ if (symbol->debug & ZINT_DEBUG_PRINT) { /* start a new level of local variables */
@ -764,6 +769,7 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
for (DPos=0 ; DPos< dataLength ; DPos++) for (DPos=0 ; DPos< dataLength ; DPos++)
fputc((pSet[DPos]&CFill)==0?'.':'X',stdout); fputc((pSet[DPos]&CFill)==0?'.':'X',stdout);
fputc('\n',stdout); fputc('\n',stdout);
printf("K1 %d, K2 %d\n", Sum1, Sum2);
} }
columns = useColumns + 5; columns = useColumns + 5;
@ -781,15 +787,17 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
for (rowCur=0 ; rowCur<rows ; rowCur++) { for (rowCur=0 ; rowCur<rows ; rowCur++) {
if (charCur>=dataLength) if (charCur>=dataLength)
{ {
/* >> Empty line with StartCCodeBCodeC */ /* >> Empty line with StartA, aCodeB, row #, and then filler aCodeC aCodeB etc */
characterSetCur=CodeC;
/* CDB Start C*/
*pOutPos='\x67'; *pOutPos='\x67';
pOutPos++; pOutPos++;
*pOutPos='\x63'; *pOutPos = 100; /* aCodeB */
pOutPos++; pOutPos++;
SumASCII(&pOutPos,rowCur+42,CodeC); characterSetCur = CodeB;
emptyColumns=useColumns-2; SumASCII(&pOutPos, rowCur + 42, characterSetCur); /* Row # */
emptyColumns = useColumns;
if (rowCur == rows - 1) {
emptyColumns -= 2;
}
while (emptyColumns>0) while (emptyColumns>0)
{ {
if(characterSetCur==CodeC) if(characterSetCur==CodeC)
@ -809,60 +817,36 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
case CodeA: case CodeA:
*pOutPos = '\x67'; *pOutPos = '\x67';
pOutPos++; pOutPos++;
if (rows>1) { *pOutPos = '\x62';
*pOutPos = '\x62'; pOutPos++;
pOutPos++;
}
characterSetCur=CodeA; characterSetCur=CodeA;
break; break;
case CodeB: case CodeB:
if (rows==1) { *pOutPos = '\x67';
*pOutPos = '\x68'; pOutPos++;
pOutPos++; *pOutPos = '\x64';
} else { pOutPos++;
*pOutPos = '\x67';
pOutPos++;
*pOutPos = '\x64';
pOutPos++;
}
characterSetCur=CodeB; characterSetCur=CodeB;
break; break;
case CodeC: case CodeC:
default: default:
if (rows==1) { *pOutPos = '\x67';
*pOutPos = '\x69'; pOutPos++;
pOutPos++; *pOutPos = '\x63';
} else { pOutPos++;
*pOutPos = '\x67';
pOutPos++;
*pOutPos = '\x63';
pOutPos++;
}
characterSetCur=CodeC; characterSetCur=CodeC;
break; break;
} }
if (rows>1) /* > Set F1 */
{ /* In first line : # of rows */
/* > Set F1 */ SumASCII(&pOutPos, rowCur == 0 ? rows - 2 : rowCur + 42, characterSetCur);
/* In first line : # of rows */
/* In Case of CodeA we shifted to CodeB */
SumASCII(&pOutPos
,(rowCur==0)?rows-2:rowCur+42
,(characterSetCur==CodeA)?CodeB:characterSetCur
);
}
/* >>> Data */ /* >>> Data */
emptyColumns=useColumns; emptyColumns=useColumns;
/* +++ One liner don't have start/stop code */
if (rows == 1)
emptyColumns +=2;
/* >> Character loop */ /* >> Character loop */
while (emptyColumns>0) while (emptyColumns > 0 && charCur < dataLength)
{ {
/* ? Change character set */ /* ? Change character set */
/* not at first position (It was then the start set) */ if (emptyColumns < useColumns)
/* +++ special case for one-liner */
if (emptyColumns<useColumns || (rows == 1 && charCur!=0) )
{ {
if ((pSet[charCur]&CodeA)!=0) if ((pSet[charCur]&CodeA)!=0)
{ {
@ -900,7 +884,7 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
A2C128_C(&pOutPos,aFNC1,'\0'); A2C128_C(&pOutPos,aFNC1,'\0');
else else
{ {
A2C128_C(&pOutPos,data[charCur],data[charCur+1]); A2C128_C(&pOutPos, data[charCur], charCur + 1 < dataLength ? data[charCur + 1] : 0);
++charCur; ++charCur;
/* We need this here to get the good index */ /* We need this here to get the good index */
/* for the termination flags in Set. */ /* for the termination flags in Set. */
@ -910,11 +894,12 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
--emptyColumns; --emptyColumns;
} }
/* >> End Criteria */ /* >> End Criteria */
if ((pSet[charCur] & CFill)!=0) if ((pSet[charCur] & CFill) || (pSet[charCur] & CEnd))
{ {
/* Fill Line but leave space for checks in last line */ /* Fill Line but leave space for checks in last line */
if(rowCur==rows-1 && emptyColumns>=2) if (rowCur == rows - 1) {
emptyColumns-=2; emptyColumns -= 2;
}
while(emptyColumns>0) while(emptyColumns>0)
{ {
switch(characterSetCur){ switch(characterSetCur){
@ -934,27 +919,23 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
--emptyColumns; --emptyColumns;
} }
} }
if ((pSet[charCur] & CEnd)!=0)
emptyColumns=0;
++charCur; ++charCur;
} /* Loop over characters */ } /* Loop over characters */
} /* if filling-Line / normal */ } /* if filling-Line / normal */
/* Add checksum in last line */ /* Add checksum in last line */
if(rows>1 && rowCur==rows-1) if (rowCur == rows - 1)
{ {
SumASCII(&pOutPos,Sum1,characterSetCur); SumASCII(&pOutPos,Sum1,characterSetCur);
SumASCII(&pOutPos,Sum2,characterSetCur); SumASCII(&pOutPos,Sum2,characterSetCur);
} }
/* Add Code 128 checksum */ /* Add Code 128 checksum */
{ {
int Sum=0; int Sum = pOutput[columns * rowCur] % 103;
int Pos=0; int Pos = 1;
for ( ; Pos < useColumns+3 ; Pos++) for ( ; Pos < useColumns+3 ; Pos++)
{ {
Sum = (Sum + Sum = (Sum + pOutput[columns * rowCur + Pos] * Pos) % 103;
((Pos==0?1:Pos) * pOutput[columns*rowCur+Pos]) % 103
) % 103;
} }
*pOutPos=(uchar)Sum; *pOutPos=(uchar)Sum;
pOutPos++; pOutPos++;
@ -981,6 +962,11 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
} }
printf("rows=%i columns=%i fillings=%i\n", rows, columns, fillings); printf("rows=%i columns=%i fillings=%i\n", rows, columns, fillings);
} }
#ifdef ZINT_TEST
if (symbol->debug & ZINT_DEBUG_TEST) {
debug_test_codeword_dump(symbol, pOutput, rows * columns);
}
#endif
/* Paint the C128 patterns */ /* Paint the C128 patterns */
for (r = 0; r < rows; r++) { for (r = 0; r < rows; r++) {
@ -992,11 +978,9 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[],
symbol->row_height[r] = 10; symbol->row_height[r] = 10;
} }
if (!(symbol->output_options & BARCODE_BIND)) { symbol->output_options |= BARCODE_BIND;
symbol->output_options += BARCODE_BIND;
}
if (symbol->border_width < 2) { if (symbol->border_width == 0) { /* Allow override if non-zero */
symbol->border_width = 2; symbol->border_width = 2;
} }
return 0; return 0;

View File

@ -40,8 +40,6 @@
#include "common.h" #include "common.h"
#include "gs1.h" #include "gs1.h"
#define TRUE 1
#define FALSE 0
#define SHIFTA 90 #define SHIFTA 90
#define LATCHA 91 #define LATCHA 91
#define SHIFTB 92 #define SHIFTB 92
@ -75,7 +73,6 @@ static const char *C128Table[107] = {
/* Determine appropriate mode for a given character */ /* Determine appropriate mode for a given character */
INTERNAL int parunmodd(const unsigned char llyth) { INTERNAL int parunmodd(const unsigned char llyth) {
int modd; int modd;
modd = 0;
if (llyth <= 31) { if (llyth <= 31) {
modd = SHIFTA; modd = SHIFTA;
@ -111,7 +108,7 @@ static void grwp(int *indexliste) {
list[0][i - 1] = list[0][i - 1] + list[0][i]; list[0][i - 1] = list[0][i - 1] + list[0][i];
j = i + 1; j = i + 1;
/* decreace the list */ /* decrease the list */
while (j < *(indexliste)) { while (j < *(indexliste)) {
list[0][j - 1] = list[0][j]; list[0][j - 1] = list[0][j];
list[1][j - 1] = list[1][j]; list[1][j - 1] = list[1][j];
@ -132,7 +129,7 @@ static void dxsmooth(int *indexliste) {
int i, last, next; int i, last, next;
for (i = 0; i < *(indexliste); i++) { for (i = 0; i < *(indexliste); i++) {
int current = list[1][i]; int current = list[1][i]; /* Either ABORC, AORB, SHIFTA or SHIFTB */
int length = list[0][i]; int length = list[0][i];
if (i != 0) { if (i != 0) {
last = list[1][i - 1]; last = list[1][i - 1];
@ -146,97 +143,82 @@ static void dxsmooth(int *indexliste) {
} }
if (i == 0) { /* first block */ if (i == 0) { /* first block */
if ((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) {
/* Rule 1a */
list[1][i] = LATCHC;
}
if (current == ABORC) { if (current == ABORC) {
if (length >= 4) { if ((*(indexliste) == 1) && (length == 2)) {
/* Rule 1a */
list[1][i] = LATCHC;
current = LATCHC;
} else if (length >= 4) {
/* Rule 1b */ /* Rule 1b */
list[1][i] = LATCHC; list[1][i] = LATCHC;
current = LATCHC;
} else { } else {
list[1][i] = AORB; current = AORB; /* Determine below */
current = AORB;
} }
} }
if (current == SHIFTA) {
/* Rule 1c */
list[1][i] = LATCHA;
}
if ((current == AORB) && (next == SHIFTA)) {
/* Rule 1c */
list[1][i] = LATCHA;
current = LATCHA;
}
if (current == AORB) { if (current == AORB) {
if (next == SHIFTA) {
/* Rule 1c */
list[1][i] = LATCHA;
} else {
/* Rule 1d */
list[1][i] = LATCHB;
}
} else if (current == SHIFTA) {
/* Rule 1c */
list[1][i] = LATCHA;
} else if (current == SHIFTB) { /* Unless LATCHC set above, can only be SHIFTB */
/* Rule 1d */ /* Rule 1d */
list[1][i] = LATCHB; list[1][i] = LATCHB;
} }
} else { } else {
if ((current == ABORC) && (length >= 4)) {
/* Rule 3 */
list[1][i] = LATCHC;
current = LATCHC;
}
if (current == ABORC) { if (current == ABORC) {
list[1][i] = AORB; if (length >= 4) {
current = AORB; /* Rule 3 */
} list[1][i] = LATCHC;
if ((current == AORB) && (last == LATCHA)) { current = LATCHC;
list[1][i] = LATCHA; } else {
current = LATCHA; current = AORB; /* Determine below */
} }
if ((current == AORB) && (last == LATCHB)) {
list[1][i] = LATCHB;
current = LATCHB;
}
if ((current == AORB) && (next == SHIFTA)) {
list[1][i] = LATCHA;
current = LATCHA;
}
if ((current == AORB) && (next == SHIFTB)) {
list[1][i] = LATCHB;
current = LATCHB;
} }
if (current == AORB) { if (current == AORB) {
list[1][i] = LATCHB; if (last == LATCHA || last == SHIFTB) { /* Maintain state */
current = LATCHB; list[1][i] = LATCHA;
} else if (last == LATCHB || last == SHIFTA) { /* Maintain state */
list[1][i] = LATCHB;
} else if (next == SHIFTA) {
list[1][i] = LATCHA;
} else {
list[1][i] = LATCHB;
}
} else if (current == SHIFTA) {
if (length > 1) {
/* Rule 4 */
list[1][i] = LATCHA;
} else if (last == LATCHA || last == SHIFTB) { /* Maintain state */
list[1][i] = LATCHA;
} else if (last == LATCHC) {
list[1][i] = LATCHA;
}
} else if (current == SHIFTB) { /* Unless LATCHC set above, can only be SHIFTB */
if (length > 1) {
/* Rule 5 */
list[1][i] = LATCHB;
} else if (last == LATCHB || last == SHIFTA) { /* Maintain state */
list[1][i] = LATCHB;
} else if (last == LATCHC) {
list[1][i] = LATCHB;
}
} }
if ((current == SHIFTA) && (length > 1)) { } /* Rule 2 is implemented elsewhere, Rule 6 is implied */
/* Rule 4 */
list[1][i] = LATCHA;
current = LATCHA;
}
if ((current == SHIFTB) && (length > 1)) {
/* Rule 5 */
list[1][i] = LATCHB;
current = LATCHB;
}
if ((current == SHIFTA) && (last == LATCHA)) {
list[1][i] = LATCHA;
current = LATCHA;
}
if ((current == SHIFTB) && (last == LATCHB)) {
list[1][i] = LATCHB;
current = LATCHB;
}
if ((current == SHIFTA) && (last == LATCHC)) {
list[1][i] = LATCHA;
current = LATCHA;
}
if ((current == SHIFTB) && (last == LATCHC)) {
list[1][i] = LATCHB;
current = LATCHB;
}
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
} }
grwp(indexliste);
grwp(indexliste);
} }
/** /**
* Translate Code 128 Set A characters into barcodes. * Translate Code 128 Set A characters into barcodes.
* This set handles all control characters NULL to US. * This set handles all control characters NUL to US.
*/ */
static void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) { static void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) {
@ -288,12 +270,12 @@ static void c128_set_c(unsigned char source_a, unsigned char source_b, char dest
(*bar_chars)++; (*bar_chars)++;
} }
/* Handle Code 128 and NVE-18 */ /* Handle Code 128, 128B and HIBC 128 */
INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) { INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length) {
int i, j, k, values[170] = {0}, bar_characters, read, total_sum; int i, j, k, values[170] = {0}, bar_characters, read, total_sum;
int error_number, indexchaine, indexliste, f_state; int error_number, indexchaine, indexliste, f_state;
int sourcelen; int sourcelen;
char set[170] = {' '}, fset[170] = {' '}, mode, last_set, current_set = ' '; char set[170] = {0}, fset[170], mode, last_set, current_set = ' ';
float glyph_count; float glyph_count;
char dest[1000]; char dest[1000];
@ -302,7 +284,6 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
sourcelen = length; sourcelen = length;
j = 0;
bar_characters = 0; bar_characters = 0;
f_state = 0; f_state = 0;
@ -315,8 +296,7 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
/* Detect extended ASCII characters */ /* Detect extended ASCII characters */
for (i = 0; i < sourcelen; i++) { for (i = 0; i < sourcelen; i++) {
if (source[i] >= 128) fset[i] = source[i] >= 128 ? 'f' : ' ';
fset[i] = 'f';
} }
fset[i] = '\0'; fset[i] = '\0';
@ -346,10 +326,15 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
for (i = 1; i < sourcelen; i++) { for (i = 1; i < sourcelen; i++) {
if ((fset[i - 1] == 'F') && (fset[i] == ' ')) { if ((fset[i - 1] == 'F') && (fset[i] == ' ')) {
/* Detected a change from 8859-1 to 646 - count how long for */ /* Detected a change from 8859-1 to 646 - count how long for */
for (j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++); for (j = 0; ((i + j) < sourcelen) && (fset[i + j] == ' '); j++);
if ((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) { /* Count how many 8859-1 beyond */
/* Uses the same figures recommended by Annex E note 3 */ k = 0;
if (i + j < sourcelen) {
for (k = 1; ((i + j + k) < sourcelen) && (fset[i + j + k] != ' '); k++);
}
if (j < 3 || (j < 5 && k > 2)) {
/* Change to shifting back rather than latching back */ /* Change to shifting back rather than latching back */
/* Inverts the same figures recommended by Annex E note 3 */
for (k = 0; k < j; k++) { for (k = 0; k < j; k++) {
fset[i + k] = 'n'; fset[i + k] = 'n';
} }
@ -427,26 +412,14 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
} }
} }
/* Adjust for strings which start with shift characters - make them latch instead */ if (symbol->debug & ZINT_DEBUG_PRINT) {
if (set[0] == 'a') { printf(" Set: %s (%d)\n", set, (int) strlen(set));
i = 0; printf("FSet: %s (%d)\n", fset, (int) strlen(fset));
do {
set[i] = 'A';
i++;
} while (set[i] == 'a');
}
if (set[0] == 'b') {
i = 0;
do {
set[i] = 'B';
i++;
} while (set[i] == 'b');
} }
/* Now we can calculate how long the barcode is going to be - and stop it from /* Now we can calculate how long the barcode is going to be - and stop it from
being too long */ being too long */
last_set = ' '; last_set = set[0];
glyph_count = 0.0; glyph_count = 0.0;
for (i = 0; i < sourcelen; i++) { for (i = 0; i < sourcelen; i++) {
if ((set[i] == 'a') || (set[i] == 'b')) { if ((set[i] == 'a') || (set[i] == 'b')) {
@ -537,7 +510,6 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
} }
} }
bar_characters++; bar_characters++;
last_set = set[0];
if (fset[0] == 'F') { if (fset[0] == 'F') {
switch (current_set) { switch (current_set) {
@ -663,18 +635,33 @@ INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const
} while (read < sourcelen); } while (read < sourcelen);
/* check digit calculation */ /* check digit calculation */
total_sum = 0; total_sum = values[0] % 103; /* Mod as we go along to avoid overflow */
for (i = 0; i < bar_characters; i++) { for (i = 1; i < bar_characters; i++) {
if (i > 0) { total_sum = (total_sum + values[i] * i) % 103;
values[i] *= i;
}
total_sum += values[i];
} }
strcat(dest, C128Table[total_sum % 103]); strcat(dest, C128Table[total_sum]);
values[bar_characters] = total_sum;
bar_characters++;
/* Stop character */ /* Stop character */
strcat(dest, C128Table[106]); strcat(dest, C128Table[106]);
values[bar_characters] = 106;
bar_characters++;
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Codewords:");
for (i = 0; i < bar_characters; i++) {
printf(" %d", values[i]);
}
printf("\n");
}
#ifdef ZINT_TEST
if (symbol->debug & ZINT_DEBUG_TEST) {
debug_test_codeword_dump_int(symbol, values, bar_characters);
}
#endif
expand(symbol, dest); expand(symbol, dest);
return error_number; return error_number;
} }
@ -687,16 +674,15 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
float glyph_count; float glyph_count;
char dest[1000]; char dest[1000];
int separator_row, linkage_flag, c_count; int separator_row, linkage_flag, c_count;
int reduced_length;
#ifndef _MSC_VER #ifndef _MSC_VER
char reduced[length + 1]; char reduced[length + 1];
#else #else
char* reduced = (char*) _alloca(length + 1); char* reduced = (char*) _alloca(length + 1);
#endif #endif
error_number = 0;
strcpy(dest, ""); strcpy(dest, "");
linkage_flag = 0; linkage_flag = 0;
j = 0;
bar_characters = 0; bar_characters = 0;
separator_row = 0; separator_row = 0;
@ -721,6 +707,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
if (error_number != 0) { if (error_number != 0) {
return error_number; return error_number;
} }
reduced_length = strlen(reduced);
/* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */
indexliste = 0; indexliste = 0;
@ -737,7 +724,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
do { do {
list[1][indexliste] = mode; list[1][indexliste] = mode;
while ((list[1][indexliste] == mode) && (indexchaine < (int) strlen(reduced))) { while ((list[1][indexliste] == mode) && (indexchaine < reduced_length)) {
list[0][indexliste]++; list[0][indexliste]++;
indexchaine++; indexchaine++;
mode = parunmodd(reduced[indexchaine]); mode = parunmodd(reduced[indexchaine]);
@ -746,7 +733,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
} }
} }
indexliste++; indexliste++;
} while (indexchaine < (int) strlen(reduced)); } while (indexchaine < reduced_length);
dxsmooth(&indexliste); dxsmooth(&indexliste);
@ -810,11 +797,16 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
} }
} }
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Data: %s (%d)\n", reduced, reduced_length);
printf(" Set: %.*s\n", reduced_length, set);
}
/* Now we can calculate how long the barcode is going to be - and stop it from /* Now we can calculate how long the barcode is going to be - and stop it from
being too long */ being too long */
last_set = ' '; last_set = set[0];
glyph_count = 0.0; glyph_count = 0.0;
for (i = 0; i < (int) strlen(reduced); i++) { for (i = 0; i < reduced_length; i++) {
if ((set[i] == 'a') || (set[i] == 'b')) { if ((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0; glyph_count = glyph_count + 1.0;
} }
@ -908,7 +900,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
bar_characters++; bar_characters++;
read++; read++;
} }
} while (read < (int) strlen(reduced)); } while (read < reduced_length);
/* "...note that the linkage flag is an extra code set character between /* "...note that the linkage flag is an extra code set character between
the last data character and the Symbol Check Character" (GS1 Specification) */ the last data character and the Symbol Check Character" (GS1 Specification) */
@ -919,7 +911,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
case 1: case 1:
case 2: case 2:
/* CC-A or CC-B 2D component */ /* CC-A or CC-B 2D component */
switch (set[strlen(reduced) - 1]) { switch (set[reduced_length - 1]) {
case 'A': linkage_flag = 100; case 'A': linkage_flag = 100;
break; break;
case 'B': linkage_flag = 99; case 'B': linkage_flag = 99;
@ -930,7 +922,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
break; break;
case 3: case 3:
/* CC-C 2D component */ /* CC-C 2D component */
switch (set[strlen(reduced) - 1]) { switch (set[reduced_length - 1]) {
case 'A': linkage_flag = 99; case 'A': linkage_flag = 99;
break; break;
case 'B': linkage_flag = 101; case 'B': linkage_flag = 101;
@ -948,22 +940,28 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s
} }
/* check digit calculation */ /* check digit calculation */
total_sum = 0; total_sum = values[0] % 103; /* Mod as we go along to avoid overflow */
for (i = 0; i < bar_characters; i++) {
if (i > 0) {
values[i] *= i;
} for (i = 1; i < bar_characters; i++) {
total_sum += values[i]; total_sum = (total_sum + values[i] * i) % 103;
} }
strcat(dest, C128Table[total_sum % 103]); strcat(dest, C128Table[total_sum]);
values[bar_characters] = total_sum % 103; values[bar_characters] = total_sum;
bar_characters++; bar_characters++;
/* Stop character */ /* Stop character */
strcat(dest, C128Table[106]); strcat(dest, C128Table[106]);
values[bar_characters] = 106; values[bar_characters] = 106;
bar_characters++; bar_characters++;
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Codewords:");
for (i = 0; i < bar_characters; i++) {
printf(" %d", values[i]);
}
printf("\n");
}
expand(symbol, dest); expand(symbol, dest);
/* Add the separator pattern for composite symbols */ /* Add the separator pattern for composite symbols */

View File

@ -206,7 +206,8 @@ INTERNAL void expand(struct zint_symbol *symbol, const char data[]) {
symbol->rows = symbol->rows + 1; symbol->rows = symbol->rows + 1;
} }
/* Indicates which symbologies can have row binding */ /* Indicates which symbologies can have row binding
* Note: if change this must also change version in frontend/main.c */
INTERNAL int is_stackable(const int symbology) { INTERNAL int is_stackable(const int symbology) {
if (symbology < BARCODE_PDF417) { if (symbology < BARCODE_PDF417) {
return 1; return 1;
@ -223,6 +224,7 @@ INTERNAL int is_stackable(const int symbology) {
case BARCODE_ITF14: case BARCODE_ITF14:
case BARCODE_CODE32: case BARCODE_CODE32:
case BARCODE_CODABLOCKF: case BARCODE_CODABLOCKF:
case BARCODE_HIBC_BLOCKF:
return 1; return 1;
} }

View File

@ -130,7 +130,7 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */
INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */
INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */
INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 128 and NVE-18 */ INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length); /* Code 128 and NVE-18 */
INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */
INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */
INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */
@ -903,6 +903,10 @@ static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_
do { do {
if (input_string[in_posn] == '\\') { if (input_string[in_posn] == '\\') {
if (in_posn + 1 >= *length) {
strcpy(symbol->errtxt, "236: Incomplete escape character in input data");
return ZINT_ERROR_INVALID_DATA;
}
switch (input_string[in_posn + 1]) { switch (input_string[in_posn + 1]) {
case '0': escaped_string[out_posn] = 0x00; /* Null */ case '0': escaped_string[out_posn] = 0x00; /* Null */
in_posn += 2; in_posn += 2;

View File

@ -1095,7 +1095,7 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int
/* Put boundary bars or box around symbol */ /* Put boundary bars or box around symbol */
if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
/* boundary bars */ /* boundary bars */
if (symbol->symbology != BARCODE_CODABLOCKF) { if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK); draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK); draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
} else { } else {
@ -1104,15 +1104,19 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int
} }
if ((symbol->output_options & BARCODE_BIND) != 0) { if ((symbol->output_options & BARCODE_BIND) != 0) {
if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
double sep_height = 2;
if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
sep_height = symbol->option_3;
}
/* row binding */ /* row binding */
if (symbol->symbology != BARCODE_CODABLOCKF) { if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
for (r = 1; r < symbol->rows; r++) { for (r = 1; r < symbol->rows; r++) {
draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height, DEFAULT_INK); draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - sep_height / 2) * 2, sep_height * 2, image_width, image_height, DEFAULT_INK);
} }
} else { } else {
for (r = 1; r < symbol->rows; r++) { for (r = 1; r < symbol->rows; r++) {
/* Avoid 11-module start and stop chars */ /* Avoid 11-module start and stop chars */
draw_bar(pixelbuf, (xoffset + 11) * 2 , (symbol->width - 22) * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height, DEFAULT_INK); draw_bar(pixelbuf, (xoffset + 11) * 2, (symbol->width - 22) * 2, ((r * row_height) + textoffset + yoffset - sep_height / 2) * 2, sep_height * 2, image_width, image_height, DEFAULT_INK);
} }
} }
} }

View File

@ -31,23 +31,33 @@
#include "testcommon.h" #include "testcommon.h"
static void test_options(int index, int debug) { static void test_large(int index, int debug) {
testStart(""); testStart("");
int ret; int ret;
struct item { struct item {
int option_1; unsigned char *pattern;
int option_2; int length;
unsigned char *data;
int ret; int ret;
char *comment; int expected_rows;
int expected_width;
}; };
// é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { -1, -1, "é", 0, "" }, /* 0*/ { "A", 2666, 0, 44, 728 },
/* 1*/ { "A", 2725, 0, 44, 739 },
/* 2*/ { "A", 2726, 0, 44, 739 }, // 4.2.1 c.3 says max 2725 but actually 44 * 62 - 2 == 2726 as mentioned later in 4.8.1
/* 3*/ { "A", 2727, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 4*/ { "12", 2726 * 2, 0, 44, 739 },
/* 5*/ { "12", 2726 * 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { "\351", 2726 / 2, 0, 44, 739 },
/* 7*/ { "\351", 2726 / 2 + 1, ZINT_ERROR_TOO_LONG, -1, -1 },
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = ARRAY_SIZE(data);
char data_buf[2726 * 2 + 2];
for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) {
@ -56,19 +66,249 @@ static void test_options(int index, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_CODABLOCKF; testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
if (data[i].option_1 != -1) { 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));
symbol->option_1 = data[i].option_1;
}
if (data[i].option_2 != -1) {
symbol->option_2 = data[i].option_2;
}
symbol->debug |= debug;
int length = strlen(data[i].data); int length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
ret = ZBarcode_Encode(symbol, 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);
if (ret < 5) {
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);
}
testFinish();
}
static void test_options(int index, int debug) {
testStart("");
int ret;
struct item {
int input_mode;
int option_1;
int option_2;
unsigned char *data;
int ret;
int expected_rows;
int expected_width;
char *comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { UNICODE_MODE, 1, -1, "é", 0, 1, 57, "CODE128" },
/* 1*/ { UNICODE_MODE, -1, -1, "A", 0, 2, 101, "Defaults" },
/* 2*/ { UNICODE_MODE, 0, -1, "A", 0, 2, 101, "0 rows same as -1" },
/* 3*/ { UNICODE_MODE, 2, -1, "A", 0, 2, 101, "Rows 2, columns default" },
/* 4*/ { UNICODE_MODE, 3, -1, "A", 0, 3, 101, "Rows 3" },
/* 5*/ { UNICODE_MODE, 43, -1, "A", 0, 43, 101, "Rows 43" },
/* 6*/ { UNICODE_MODE, 44, -1, "A", 0, 44, 101, "Max rows" },
/* 7*/ { UNICODE_MODE, 45, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "" },
/* 8*/ { UNICODE_MODE, -1, -1, "abcdefg", 0, 3, 101, "" },
/* 9*/ { UNICODE_MODE, 2, -1, "abcdefg", 0, 2, 112, "Rows given so columns expanded" },
/* 10*/ { UNICODE_MODE, 3, -1, "abcdefg", 0, 3, 101, "" },
/* 11*/ { UNICODE_MODE, -1, 8, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "Min columns 9 (4 data)" },
/* 12*/ { UNICODE_MODE, -1, 9, "A", 0, 2, 101, "Min columns 9 (4 data)" },
/* 13*/ { UNICODE_MODE, -1, 10, "A", 0, 2, 112, "Columns 10" },
/* 14*/ { UNICODE_MODE, -1, 66, "A", 0, 2, 728, "Columns 66" },
/* 15*/ { UNICODE_MODE, -1, 67, "A", 0, 2, 739, "Max columns 67 (62 data)" },
/* 16*/ { UNICODE_MODE, -1, 68, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "" },
/* 17*/ { UNICODE_MODE, 2, 9, "A", 0, 2, 101, "Rows and columns defaults given" },
/* 18*/ { UNICODE_MODE, 2, 10, "A", 0, 2, 112, "Rows and columns given" },
/* 19*/ { UNICODE_MODE, 3, 11, "A", 0, 3, 123, "" },
/* 20*/ { UNICODE_MODE, 43, 66, "A", 0, 43, 728, "" },
/* 21*/ { UNICODE_MODE, 44, 67, "A", 0, 44, 739, "Max rows, max columns" },
/* 22*/ { GS1_MODE, -1, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "GS1 not supported" },
/* 23*/ { GS1_MODE, 1, -1, "A", ZINT_ERROR_INVALID_OPTION, -1, -1, "Check for CODE128" },
};
int data_size = ARRAY_SIZE(data);
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, data[i].data, length); ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (ret < 5) {
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);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_reader_init(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
int symbology;
int input_mode;
int output_options;
unsigned char *data;
int ret;
int expected_rows;
int expected_width;
char *expected;
char *comment;
};
struct item data[] = {
/* 0*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 16, "1234", 0, 2, 101, "67 64 40 60 63 0C 22 2B 6A 67 64 0B 63 64 3A 1C 29 6A", "CodeB FNC3 CodeC 12 34 / CodeB Pads" },
/* 1*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, 16, "123456", 0, 3, 101, "67 64 41 60 0B 11 12 22 6A 67 63 2B 22 38 64 2A 1B 6A 67 64 0C 63 64 2B 2F 52 6A", "CodeB FNC3 + 1 2 / CodeC 34 56 CodeB J" },
};
int data_size = ARRAY_SIZE(data);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int 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, 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);
if (generate) {
printf(" /*%3d*/ { %s, %s, %d, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), 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 < 5) {
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);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_input(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
int symbology;
int input_mode;
int option_2;
unsigned char *data;
int length;
int ret;
int expected_rows;
int expected_width;
char *expected;
char *comment;
};
// NUL U+0000, CodeA-only
// US U+001F (\037, 31), CodeA-only
// a U+0061 (\141, 97), CodeB-only
// DEL U+007F (\177, 127), CodeB-only
// PAD U+0080 (\200, 128), UTF-8 C280 (\302\200), CodeA-only extended ASCII, not in ISO 8859-1
// APC U+009F (\237, 159), UTF-8 C29F, CodeA-only extended ASCII, not in ISO 8859-1
// NBSP U+00A0 (\240, 160), UTF-8 C2A0, CodeA and CodeB extended ASCII
// ß U+00DF (\337, 223), UTF-8 C39F, CodeA and CodeB extended ASCII
// à U+00E0 (\340, 224), UTF-8 C3A0, CodeB-only extended ASCII
// á U+00E1 (\341, 225), UTF-8 C3A1, CodeB-only extended ASCII
// é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
// ñ U+00F1 (\361, 241), UTF-8 C3B1, CodeB-only extended ASCII
// ÿ U+00FF (\377, 255), UTF-8 C3BF, CodeB-only extended ASCII
struct item data[] = {
/* 0*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "A", -1, 0, 2, 101, "67 64 40 21 63 64 63 42 6A 67 64 0B 63 64 2B 40 4F 6A", "Fillings 5" },
/* 1*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAA", -1, 0, 2, 101, "67 64 40 21 21 21 63 55 6A 67 64 0B 63 64 0E 57 48 6A", "Fillings 3" },
/* 2*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 63 64 1A 0E 03 6A", "Fillings 2" },
/* 3*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 21 63 1D 30 14 6A", "Fillings 1" },
/* 4*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "AAAAAA", -1, 0, 2, 101, "67 64 40 21 21 21 21 65 6A 67 64 0B 21 21 35 5D 2B 6A", "Fillings 0" },
/* 5*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234", -1, 0, 2, 101, "67 63 00 0C 22 64 63 1A 6A 67 64 0B 63 64 3A 1C 29 6A", "Fillings 4" },
/* 6*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "12345", -1, 0, 2, 101, "67 63 00 0C 22 64 15 49 6A 67 64 0B 63 64 41 44 07 6A", "Fillings 2 (not counting CodeB at end of 1st line)" },
/* 7*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "123456", -1, 0, 2, 101, "67 63 00 0C 22 38 64 12 6A 67 64 0B 63 64 2D 50 52 6A", "Fillings 3" },
/* 8*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234567", -1, 0, 2, 101, "67 63 00 0C 22 38 64 12 6A 67 64 0B 17 63 16 02 5B 6A", "Fillings 1 (not counting CodeB at end of 1st line)" },
/* 9*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "12345678", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 63 64 08 1C 64 6A", "Fillings 2" },
/* 10*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "123456789", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 19 63 25 4C 65 6A", "Fillings 1" },
/* 11*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "1234567890", -1, 0, 2, 101, "67 63 00 0C 22 38 4E 5C 6A 67 64 0B 19 10 41 38 62 6A", "Fillings 0" },
/* 12*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "A123ñ", -1, 0, 2, 101, "67 64 40 21 11 12 13 54 6A 67 64 0B 64 51 42 28 50 6A", "K1/K2 example in Annex F" },
/* 13*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "", -1, 0, 2, 101, "67 64 40 41 64 3F 63 54 6A 67 64 0B 63 64 5B 1D 06 6A", "CodeB a FNC4 ß fits 1st line" },
/* 14*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037ß", -1, 0, 2, 101, "67 62 40 5F 65 3F 63 49 6A 67 64 0B 63 64 0F 1D 26 6A", "CodeA US FNC4 ß fits 1st line" },
/* 15*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaß", -1, 0, 2, 101, "67 64 40 41 41 64 3F 10 6A 67 64 0B 63 64 4E 5B 04 6A", "CodeB a a FNC4 ß fits 1st line" },
/* 16*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037ß", -1, 0, 2, 101, "67 62 40 5F 5F 65 3F 17 6A 67 64 0B 63 64 34 0F 24 6A", "CodeA US US FNC4 ß fits 1st line" },
/* 17*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaaß", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 64 0B 64 3F 4C 4E 50 6A", "CodeB a (3) / CodeB FNC4 ß fully on next line" },
/* 18*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037\037ß", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 64 0B 64 3F 0E 34 1A 6A", "CodeA US (3) / CodeB FNC4 ß fully on next line" },
/* 19*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "", -1, 0, 2, 101, "67 64 40 41 64 40 63 59 6A 67 64 0B 63 64 5D 1E 16 6A", "CodeB a FNC4 à fits 1st line" },
/* 20*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037à", -1, 0, 2, 101, "67 62 40 5F 65 62 40 26 6A 67 64 0B 63 64 1B 1E 01 6A", "CodeA US FNC4 Shift à fits 1st line" },
/* 21*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037àa", -1, 0, 2, 101, "67 62 40 5F 64 64 40 2C 6A 67 64 0B 41 63 52 4A 16 6A", "CodeA US LatchB FNC4 à fits 1st line / Code B a" },
/* 22*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaà", -1, 0, 2, 101, "67 64 40 41 41 64 40 16 6A 67 64 0B 63 64 51 5D 1F 6A", "CodeB a a FNC4 à fits 1st line" },
/* 23*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037à", -1, 0, 2, 101, "67 62 40 5F 5F 63 64 1D 6A 67 64 0B 64 40 37 1B 55 6A", "CodeA US US / Code B FNC4 à fully on next line" },
/* 24*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "aaaà", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 64 0B 64 40 50 51 13 6A", "CodeB a (3) / Code B FNC4 à fully on next line" },
/* 25*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\037\037\037à", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 64 0B 64 40 1C 37 0F 6A", "CodeA US (3) / CodeB FNC4 à fully on next line" },
/* 26*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\200", -1, 0, 2, 101, "67 62 40 5F 65 40 63 4E 6A 67 64 0B 63 64 5D 0A 05 6A", "CodeA US FNC4 PAD fits 1st line" },
/* 27*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\200", -1, 0, 2, 101, "67 64 40 41 64 62 40 31 6A 67 64 0B 63 64 49 0A 08 6A", "CodeB a FNC4 Shift PAD fits 1st line" },
/* 28*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\200\037", -1, 0, 2, 101, "67 64 40 41 65 65 40 44 6A 67 62 0B 5F 63 10 12 3E 6A", "CodeB a LatchA FNC4 PAD fits 1st line / CodeA US" },
/* 29*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\037\200", -1, 0, 2, 101, "67 62 40 5F 5F 65 40 1D 6A 67 64 0B 63 64 0F 5D 0A 6A", "CodeA US US FNC4 PAD fits 1st line" },
/* 30*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\141\200", -1, 0, 2, 101, "67 64 40 41 41 63 64 1B 6A 67 62 0B 65 40 33 49 21 6A", "CodeB a a / CodeA FNC4 PAD fully on next line" },
/* 31*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\037\037\037\200", -1, 0, 2, 101, "67 62 40 5F 5F 5F 63 03 6A 67 62 0B 65 40 4A 0F 06 6A", "CodeA US (3) / CodeA FNC4 PAD fully on next line" },
/* 32*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\141\141\141\200", -1, 0, 2, 101, "67 64 40 41 41 41 63 39 6A 67 62 0B 65 40 28 33 34 6A", "CodeB a (3) / CodeA FNC4 PAD fully on next line" },
/* 33*/ { BARCODE_CODABLOCKF, DATA_MODE, 10, "\200\240\237\340\337\341\377", -1, 0, 4, 112, "(40) 67 62 42 65 40 65 00 63 1E 6A 67 62 0B 65 5F 64 64 40 55 6A 67 64 0C 64 3F 64 41 63", "" },
/* 34*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "\000a\037\177}12", 7, 0, 3, 101, "67 62 41 40 62 41 5F 3B 6A 67 64 0B 5F 5D 11 12 2D 6A 67 64 0C 63 64 40 05 26 6A", "" },
/* 35*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "abcdéf", -1, 0, 3, 101, "67 64 41 41 42 43 44 5D 6A 67 64 0B 64 49 46 63 0A 6A 67 64 0C 63 64 4F 26 02 6A", "" },
/* 36*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, "a12é\000", 6, 0, 3, 101, "67 64 41 41 11 12 63 2C 6A 67 64 0B 64 49 62 40 2B 6A 67 64 0C 63 64 33 34 31 6A", "" },
/* 37*/ { BARCODE_HIBC_BLOCKF, UNICODE_MODE, -1, "A99912345/$$52001510X3", -1, 0, 6, 101, "(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", "" },
};
int data_size = ARRAY_SIZE(data);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
ret = ZBarcode_Encode(symbol, 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);
if (generate) {
printf(" /*%3d*/ { %s, %s, %d, \"%s\", %d, %s, %d, %d, \"%s\", \"%s\" },\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].option_2,
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment);
} else {
if (ret < 5) {
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);
}
}
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
} }
@ -82,7 +322,7 @@ static void test_encode(int index, int generate, int debug) {
int ret; int ret;
struct item { struct item {
int input_mode; int symbology;
int option_1; int option_1;
int option_2; int option_2;
unsigned char *data; unsigned char *data;
@ -94,39 +334,81 @@ static void test_encode(int index, int generate, int debug) {
char *expected; char *expected;
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, "AIM", 0, 1, 68, "Same as CODE128", /* 0*/ { BARCODE_CODABLOCKF, 1, -1, "AIM", 0, 1, 68, "Same as CODE128",
"11010010000101000110001100010001010111011000101110110001100011101011" "11010010000101000110001100010001010111011000101110110001100011101011"
}, },
/* 1*/ { UNICODE_MODE, -1, -1, "AAAAAAAAA", 0, 4, 90, "", /* 1*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAA", 0, 3, 101, "Defaults to rows 3, columns 9 (4 data); verified manually against bwipp and tec-it",
"110100001001011110111010010000110101000110001010001100010100011000110010001001100011101011" "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011"
"110100001001011110111011000100100101000110001010001100010100011000100100110001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010111011110100100111101100011101011"
"110100001001011110111010110011100101000110001010001100010100011000100010011001100011101011" "11010000100101111011101011001110010111011110101111011101100001010011011101110111100101001100011101011"
"110100001001011101111010111011000101111011101001011000010010011110111001001101100011101011" },
}, /* 2*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAA", 0, 3, 101, "Defaults to rows 3, columns 9 (4 data); verified manually against bwipp and tec-it",
/* 2*/ { UNICODE_MODE, 3, -1, "AAAAAAAAA", 0, 3, 101, "Verified manually against tec-it (bwipp differs)",
"11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011" "11010000100101111011101001011000010100011000101000110001010001100010100011000110110011001100011101011"
"11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
"11010000100101111011101011001110010100011000101110111101100110110011001110010110001001001100011101011" "11010000100101111011101011001110010100011000101000110001110110010010010110000111000101101100011101011"
}, },
/* 3*/ { UNICODE_MODE, -1, -1, "AAAAAAAAAAAAAAA", 0, 6, 90, "", /* 3*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAA", 0, 4, 101, "Defaults to rows 4, columns 9 (4 data); verified manually against bwipp and tec-it",
"110100001001011110111010000100110101000110001010001100010100011000100110011101100011101011" "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011"
"110100001001011110111011000100100101000110001010001100010100011000100100110001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
"110100001001011110111010110011100101000110001010001100010100011000100010011001100011101011" "11010000100101111011101011001110010100011000101000110001010001100010111011110100111101001100011101011"
"110100001001011110111010011011100101000110001010001100010100011000100110001001100011101011" "11010000100101111011101001101110010111011110101111011101110101100011101100100110010111001100011101011"
"110100001001011110111010011001110101000110001010001100010100011000110010010001100011101011" },
"110100001001011101111010001110110101111011101000110001010111101000110111101101100011101011" /* 4*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAA", 0, 4, 101, "Defaults to rows 4, columns 9 (4 data); verified manually against bwipp and tec-it",
}, "11010000100101111011101001000011010100011000101000110001010001100010100011000110011001101100011101011"
/* 4*/ { UNICODE_MODE, -1, 14, "AAAAAAAAAAAAAAA", 0, 2, 156, "", "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
"11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
"11010000100101111011101001101110010100011000101000110001011110100010111011000100110000101100011101011"
},
/* 5*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAA", 0, 5, 101, "Defaults to rows 5, columns 9 (4 data); verified manually against bwipp (columns=4) and tec-it",
"11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011"
"11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
"11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
"11010000100101111011101001101110010100011000101000110001010001100010111011110111101001001100011101011"
"11010000100101111011101001100111010111011110101111011101000110001010111101000110001010001100011101011"
},
/* 6*/ { BARCODE_CODABLOCKF, -1, 14, "AAAAAAAAAAAAAAA", 0, 2, 156, "Rows 2, columns 14 (9 data); verified manually against bwipp (columns=9) and tec-it",
"110100001001011110111010100001100101000110001010001100010100011000101000110001010001100010100011000101000110001010001100010100011000110001000101100011101011" "110100001001011110111010100001100101000110001010001100010100011000101000110001010001100010100011000101000110001010001100010100011000110001000101100011101011"
"110100001001011110111011000100100101000110001010001100010100011000101000110001010001100010100011000101110111101110111101011011000110111000101101100011101011" "110100001001011110111011000100100101000110001010001100010100011000101000110001010001100010100011000101110111101110111101011011000110111000101101100011101011"
}, },
/* 5*/ { UNICODE_MODE, 3, -1, "AAAAAAAAAAAAAAA", 0, 3, 123, "Differs from tec-it (and bwipp); TODO: verify", /* 7*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAA", 0, 5, 101, "Defaults to rows 5, columns 9 (4 data); verified manually against bwipp (columns=4) and tec-it",
"110100001001011110111010010110000101000110001010001100010100011000101000110001010001100010100011000101111001001100011101011" "11010000100101111011101000010110010100011000101000110001010001100010100011000100100011001100011101011"
"110100001001011110111011000100100101000110001010001100010100011000101000110001010001100010100011000110000101001100011101011" "11010000100101111011101100010010010100011000101000110001010001100010100011000111101000101100011101011"
"110100001001011110111010110011100101000110001010001100010100011000101110111101110111101011011000110110110001101100011101011" "11010000100101111011101011001110010100011000101000110001010001100010100011000101111011101100011101011"
}, "11010000100101111011101001101110010100011000101000110001010001100010100011000111101011101100011101011"
"11010000100101111011101001100111010111011110101111011101011100011010001100010100011101101100011101011"
},
/* 8*/ { BARCODE_CODABLOCKF, -1, -1, "AAAAAAAAAAAAAAAAAAAAAAAAA", 0, 6, 112, "Defaults to rows 6, columns 10 (5 data); verified manually against bwipp (columns=5) and tec-it",
"1101000010010111101110100001001101010001100010100011000101000110001010001100010100011000110110001101100011101011"
"1101000010010111101110110001001001010001100010100011000101000110001010001100010100011000110010011101100011101011"
"1101000010010111101110101100111001010001100010100011000101000110001010001100010100011000110011101001100011101011"
"1101000010010111101110100110111001010001100010100011000101000110001010001100010100011000111010011001100011101011"
"1101000010010111101110100110011101010001100010100011000101000110001010001100010100011000111001001101100011101011"
"1101000010010111101110101110011001011101111010111101110101110111101110100011010100001100110001010001100011101011"
},
/* 9*/ { BARCODE_CODABLOCKF, 4, -1, "CODABLOCK F 34567890123456789010040digit", 0, 4, 145, "AIM ISS-X-24 Figure 1",
"1101000010010111101110100100001101000100011010001110110101100010001010001100010001011000100011011101000111011010001000110110110011001100011101011"
"1101000010010111101110110001001001011000111011011001100100011000101101100110010111011110100010110001110001011011000010100101100111001100011101011"
"1101000010010111011110100011011101101111011010110011100100010110001110001011011000010100110111101101100100010010010001100100011000101100011101011"
"1101000010010111101110100110111001001110110010000100110100001101001001101000010000110100100111101001101110111010111000110110010000101100011101011"
},
/* 10*/ { BARCODE_CODABLOCKF, 3, -1, "CODABLOCK F Symbology", 0, 3, 145, "AIM ISS-X-24 Figure on front page",
"1101000010010111101110100101100001000100011010001110110101100010001010001100010001011000100011011101000111011010001000110111010111101100011101011"
"1101000010010111101110110001001001011000111011011001100100011000101101100110011011101000110110111101111011101010010000110100100111101100011101011"
"1101000010010111101110101100111001000111101011001010000100011110101001101000011011011110101110111101000011001011011101110101001111001100011101011"
},
/* 11*/ { BARCODE_HIBC_BLOCKF, 3, -1, "A123BJC5D6E71", 0, 3, 123, "Verified manually against tec-it; differs from bwipp (columns=6) which uses Code C for final 71 (same no. of codewords)",
"110100001001011110111010010110000110001001001010001100010011100110110011100101100101110010001011000100100001101100011101011"
"110100001001011110111011000100100101101110001000100011011011100100101100010001100111010010001101000111001001101100011101011"
"110100001001011110111010110011100111011011101001110011011010001000101110111101011100011011001110100100100110001100011101011"
},
/* 12*/ { BARCODE_HIBC_BLOCKF, -1, -1, "$$52001510X3G", 0, 4, 101, "Verified manually against bwipp (columns=4); tec-it differs as adds unnecessary Code C at end of 1st line",
"11010000100101111011101001000011011000100100100100011001001000110011011100100101110011001100011101011"
"11010000100101110111101011000111011001001110110011011001101110100010111101110100001100101100011101011"
"11010000100101111011101011001110010011101100111000101101100101110011010001000100100011001100011101011"
"11010000100101111011101001101110010110001000101110111101101000111011000110110100011010001100011101011"
},
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = ARRAY_SIZE(data);
char escaped[1024]; char escaped[1024];
@ -137,27 +419,17 @@ static void test_encode(int index, int generate, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_CODABLOCKF; int length = testUtilSetSymbol(symbol, data[i].symbology, UNICODE_MODE, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
symbol->input_mode = data[i].input_mode;
if (data[i].option_1 != -1) {
symbol->option_1 = data[i].option_1;
}
if (data[i].option_2 != -1) {
symbol->option_2 = data[i].option_2;
}
symbol->debug |= debug;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length); ret = ZBarcode_Encode(symbol, 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 (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, %d, \"%s\", %s, %d, %d, \"%s\",\n", printf(" /*%3d*/ { %s, %d, %d, \"%s\", %s, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), i, testUtilBarcodeName(data[i].symbology), data[i].option_1, data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment); testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n"); testUtilModulesDump(symbol, " ", "\n");
printf(" },\n"); printf(" },\n");
} else { } else {
if (ret < 5) { if (ret < 5) {
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->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
@ -201,13 +473,7 @@ static void test_fuzz(int index, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_CODABLOCKF; int length = testUtilSetSymbol(symbol, BARCODE_CODABLOCKF, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
symbol->debug |= debug;
int length = data[i].length;
if (length == -1) {
length = strlen(data[i].data);
}
ret = ZBarcode_Encode(symbol, data[i].data, length); ret = ZBarcode_Encode(symbol, 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);
@ -221,7 +487,10 @@ static void test_fuzz(int index, int debug) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_large", test_large, 1, 0, 1 },
{ "test_options", test_options, 1, 0, 1 }, { "test_options", test_options, 1, 0, 1 },
{ "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
}; };

View File

@ -29,9 +29,76 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
/* Note BARCODE_EAN128, BARCODE_EAN14, BARCODE_NVE18 also tested in test_gs1.c */
#include "testcommon.h" #include "testcommon.h"
static void test_input(int index, int debug) { static void test_large(int index, int debug) {
testStart("");
int ret;
struct item {
int symbology;
unsigned char *pattern;
int length;
int ret;
int expected_width;
};
// é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_CODE128, "A", 60, 0, 695 },
/* 1*/ { BARCODE_CODE128, "A", 61, ZINT_ERROR_TOO_LONG, -1 },
/* 2*/ { BARCODE_CODE128, "\351A", 40, 0, 695 },
/* 3*/ { BARCODE_CODE128, "\351A", 41, ZINT_ERROR_TOO_LONG, -1 }, // 41 chars (+ 20 shifts)
/* 4*/ { BARCODE_CODE128, "0", 120, 0, 695 },
/* 5*/ { BARCODE_CODE128, "0", 121, ZINT_ERROR_TOO_LONG, -1 },
/* 6*/ { BARCODE_CODE128B, "A", 60, 0, 695 },
/* 7*/ { BARCODE_CODE128B, "A", 61, ZINT_ERROR_TOO_LONG, -1 },
/* 8*/ { BARCODE_CODE128B, "0", 60, 0, 695 },
/* 9*/ { BARCODE_CODE128B, "0", 61, ZINT_ERROR_TOO_LONG, -1 },
/* 10*/ { BARCODE_EAN128, "[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234567890[92]1234567890", -1, 0, 706 }, // 116 nos + 3 FNC1s
/* 11*/ { BARCODE_EAN128, "[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234567890[92]1234[93]1234", -1, ZINT_ERROR_TOO_LONG, -1 }, // 116 nos + 4 FNC1s
/* 12*/ { BARCODE_EAN14, "1234567890123", -1, 0, 134 },
/* 13*/ { BARCODE_EAN14, "12345678901234", -1, ZINT_ERROR_TOO_LONG, -1 },
/* 14*/ { BARCODE_NVE18, "12345678901234567", -1, 0, 156 },
/* 15*/ { BARCODE_NVE18, "123456789012345678", -1, ZINT_ERROR_TOO_LONG, -1 },
};
int data_size = ARRAY_SIZE(data);
char data_buf[4096];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
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));
} else {
strcpy(data_buf, data[i].pattern);
}
int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
ret = ZBarcode_Encode(symbol, 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);
if (ret < 5) {
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);
}
testFinish();
}
static void test_hrt(int index, int debug) {
testStart(""); testStart("");
@ -41,18 +108,164 @@ static void test_input(int index, int debug) {
int input_mode; int input_mode;
unsigned char *data; unsigned char *data;
int length; int length;
int ret;
unsigned char *expected;
}; };
// é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_CODE128, UNICODE_MODE, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", -1, 0 }, // 59 chars /* 0*/ { BARCODE_CODE128, UNICODE_MODE, "1234567890", -1, "1234567890" },
/* 1*/ { BARCODE_CODE128, UNICODE_MODE, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", -1, ZINT_ERROR_TOO_LONG }, // 60 chars /* 1*/ { BARCODE_CODE128, UNICODE_MODE, "\000ABC\000DEF\000", 9, " ABC DEF " },
/* 2*/ { BARCODE_CODE128, UNICODE_MODE, "éAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAé", -1, 0 }, // 39 chars /* 2*/ { BARCODE_CODE128B, UNICODE_MODE, "12345\00067890", 11, "12345 67890" },
/* 3*/ { BARCODE_CODE128, UNICODE_MODE, "éAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéAéA", -1, ZINT_ERROR_TOO_LONG }, // 40 chars (+ 20 shifts) /* 3*/ { BARCODE_CODE128, UNICODE_MODE, "12345\01167890\037\177", -1, "12345\01167890\037\177" },
/* 4*/ { BARCODE_CODE128, UNICODE_MODE, "\302\200", -1, ZINT_ERROR_INVALID_DATA }, // PAD U+0080, not in ISO 8859-1 although encodable in CODE128 /* 4*/ { BARCODE_CODE128, UNICODE_MODE, "abcdé", -1, "abcdé" },
/* 5*/ { BARCODE_CODE128, DATA_MODE, "\302\200", -1, 0 }, // PAD U+0080, use binary /* 5*/ { BARCODE_CODE128, DATA_MODE, "abcd\351", -1, "abcd\351" },
/* 6*/ { BARCODE_CODE128, UNICODE_MODE, "\000\037é", 4, 0 }, /* 6*/ { BARCODE_CODE128B, UNICODE_MODE, "abcdé", -1, "abcdé" },
/* 7*/ { BARCODE_CODE128B, UNICODE_MODE, "\000\037é", 4, 0 }, /* 7*/ { BARCODE_CODE128B, DATA_MODE, "abcd\351", -1, "abcd\351" },
// BARCODE_EAN128, BARCODE_EAN14, BARCODE_NVE18 hrt tested in test_gs1.c
};
int data_size = ARRAY_SIZE(data);
char *text;
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 %s\n", i, ret, symbol->errtxt);
assert_zero(strcmp(symbol->text, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->text, data[i].expected);
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_reader_init(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
int symbology;
int input_mode;
int output_options;
unsigned char *data;
int ret;
int expected_rows;
int expected_width;
char *expected;
char *comment;
};
struct item data[] = {
/* 0*/ { BARCODE_CODE128, UNICODE_MODE, 16, "A", 0, 1, 57, "(5) 104 96 33 60 106", "StartA FNC3 A" },
/* 1*/ { BARCODE_CODE128, UNICODE_MODE, 16, "12", 0, 1, 68, "(6) 104 96 99 12 22 106", "StartB FNC3 CodeC 12" },
/* 2*/ { BARCODE_CODE128B, UNICODE_MODE, 16, "\0371234", 0, 1, 101, "(9) 103 96 95 17 18 19 20 6 106", "StartA FNC3 US 1 2 3 4" },
/* 3*/ { BARCODE_EAN128, GS1_MODE, 16, "[90]12", 0, 1, 68, "", "Reader Initialise not supported by GS1 barcodes (use CODE128)" },
/* 4*/ { BARCODE_EAN14, GS1_MODE, 16, "12", 0, 1, 134, "", "Reader Initialise not supported by GS1 barcodes (use CODE128)" },
/* 5*/ { BARCODE_NVE18, GS1_MODE, 16, "12", 0, 1, 156, "", "Reader Initialise not supported by GS1 barcodes (use CODE128)" },
};
int data_size = ARRAY_SIZE(data);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int 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, 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);
if (generate) {
printf(" /*%3d*/ { %s, %s, %d, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), 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 < 5) {
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);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_input(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
int input_mode;
unsigned char *data;
int length;
int ret;
int expected_width;
char *expected;
char *comment;
};
// NUL U+0000, CodeA-only
// US U+001F (\037, 31), CodeA-only
// a U+0061 (\141, 97), CodeB-only
// b U+0062 (\142, 98), CodeB-only
// PAD U+0080 (\200, 128), UTF-8 C280 (\302\200), CodeA-only extended ASCII, not in ISO 8859-1
// APC U+009F (\237, 159), UTF-8 C29F, CodeA-only extended ASCII, not in ISO 8859-1
// ß U+00DF (\337, 223), UTF-8 C39F, CodeA and CodeB extended ASCII
// é U+00E9 (\351, 233), UTF-8 C3A9, CodeB-only extended ASCII
struct item data[] = {
/* 0*/ { UNICODE_MODE, "\302\200", -1, ZINT_ERROR_INVALID_DATA, 0, "Error 204: Invalid characters in input data", "PAD not in ISO 8859-1" },
/* 1*/ { DATA_MODE, "\200", -1, 0, 57, "(5) 103 101 64 23 106", "PAD ok using binary" },
/* 2*/ { UNICODE_MODE, "AIM1234", -1, 0, 101, "(9) 104 33 41 45 99 12 34 87 106", "Example from Annex A.1, check char value 87" },
/* 3*/ { GS1_MODE, "[90]12", -1, ZINT_ERROR_INVALID_OPTION, 0, "Error 220: Selected symbology does not support GS1 mode", "" },
/* 4*/ { UNICODE_MODE, "1", -1, 0, 46, "(4) 104 17 18 106", "StartB 1" },
/* 5*/ { UNICODE_MODE, "12", -1, 0, 46, "(4) 105 12 14 106", "StartC 12" },
/* 6*/ { UNICODE_MODE, "123", -1, 0, 68, "(6) 104 17 18 19 8 106", "StartB 1 2 3" },
/* 7*/ { UNICODE_MODE, "1234", -1, 0, 57, "(5) 105 12 34 82 106", "StartC 12 34" },
/* 8*/ { UNICODE_MODE, "12345", -1, 0, 79, "(7) 105 12 34 100 21 54 106", "StartC 12 34 CodeB 5" },
/* 9*/ { UNICODE_MODE, "\037", -1, 0, 46, "(4) 103 95 95 106", "StartA US" },
/* 10*/ { UNICODE_MODE, "1\037", -1, 0, 57, "(5) 103 17 95 1 106", "StartA 1 US" },
/* 11*/ { UNICODE_MODE, "12\037", -1, 0, 68, "(6) 103 17 18 95 29 106", "StartA 1 2 US" },
/* 12*/ { UNICODE_MODE, "a\037a", -1, 0, 79, "(7) 104 65 98 95 65 86 106", "StartB a Shift US a" },
/* 13*/ { UNICODE_MODE, "1234\037a", -1, 0, 101, "(9) 105 12 34 101 95 98 65 100 106", "StartC 12 34 CodeA US Shift a" },
/* 14*/ { UNICODE_MODE, "\037AAa\037", -1, 0, 101, "(9) 103 95 33 33 98 65 95 2 106", "StartA US A A Shift a US" },
/* 15*/ { UNICODE_MODE, "\037AAaa\037", -1, 0, 123, "(11) 103 95 33 33 100 65 65 98 95 40 106", "StartA US A A CodeB a a Shift US" },
/* 16*/ { UNICODE_MODE, "AAAa12345aAA", -1, 0, 167, "(15) 104 33 33 33 65 17 99 23 45 100 65 33 33 54 106", "StartB A (3) a 1 CodeC 23 45 CodeB a A A" },
/* 17*/ { UNICODE_MODE, "a\037Aa\037\037a\037aa\037a", -1, 0, 222, "(20) 104 65 98 95 33 65 101 95 95 98 65 95 100 65 65 98 95 65 96 106", "StartB a Shift US A a CodeA US US Shift a US CodeB a a Shift US a" },
/* 18*/ { UNICODE_MODE, "\000\037ß", 4, 0, 79, "(7) 103 64 95 101 63 88 106", "StartA NUL US FNC4 ß" },
/* 19*/ { UNICODE_MODE, "\000\037é", 4, 0, 90, "(8) 103 64 95 101 98 73 78 106", "StartA NUL US FNC4 Shift é" },
/* 20*/ { UNICODE_MODE, "\000\037éa", 5, 0, 101, "(9) 103 64 95 100 100 73 65 61 106", "StartA NUL US LatchB FNC4 é a" },
/* 21*/ { UNICODE_MODE, "abß", -1, 0, 79, "(7) 104 65 66 100 63 29 106", "StartB a b FNC4 ß" },
/* 22*/ { DATA_MODE, "\141\142\237", -1, 0, 90, "(8) 104 65 66 100 98 95 26 106", "StartB a b FNC4 Shift APC" },
/* 23*/ { DATA_MODE, "\141\142\237\037", -1, 0, 101, "(9) 104 65 66 101 101 95 95 96 106", "StartB a b LatchA FNC4 APC US" },
/* 24*/ { UNICODE_MODE, "ééé", -1, 0, 90, "(8) 104 100 100 73 73 73 44 106", "StartB LatchFNC4 é é é" },
/* 25*/ { UNICODE_MODE, "aééééb", -1, 0, 145, "(13) 104 65 100 73 100 73 100 73 100 73 66 49 106", "StartB a FNC4 é (4) b" },
/* 26*/ { UNICODE_MODE, "aéééééb", -1, 0, 145, "(13) 104 65 100 100 73 73 73 73 73 100 66 93 106", "StartB a Latch é (5) Shift b" },
/* 27*/ { UNICODE_MODE, "aééééébc", -1, 0, 167, "(15) 104 65 100 100 73 73 73 73 73 100 66 100 67 40 106", "StartB a Latch é (5) Shift b Shift c" },
/* 28*/ { UNICODE_MODE, "aééééébcd", -1, 0, 178, "(16) 104 65 100 100 73 73 73 73 73 100 100 66 67 68 66 106", "StartB a Latch é (5) Unlatch b c d" },
/* 29*/ { UNICODE_MODE, "aééééébcde", -1, 0, 189, "(17) 104 65 100 100 73 73 73 73 73 100 100 66 67 68 69 2 106", "StartB a Latch é (5) Unlatch b c d e" },
/* 30*/ { UNICODE_MODE, "aééééébcdeé", -1, 0, 211, "(19) 104 65 100 100 73 73 73 73 73 100 100 66 67 68 69 100 73 95 106", "StartB a Latch é (5) Unlatch b c d e FNC4 é" },
/* 31*/ { UNICODE_MODE, "aééééébcdeéé", -1, 0, 233, "(21) 104 65 100 100 73 73 73 73 73 100 100 66 67 68 69 100 73 100 73 19 106", "StartB a Latch é (5) Unlatch b c d e FNC4 é (2)" },
/* 32*/ { UNICODE_MODE, "aééééébcdeééé", -1, 0, 244, "(22) 104 65 100 100 73 73 73 73 73 100 66 100 67 100 68 100 69 73 73 73 83 106", "StartB a Latch é (5) Shift b Shift c Shift d Shift e é (3)" },
/* 33*/ { UNICODE_MODE, "aééééébcdefééé", -1, 0, 255, "(23) 104 65 100 100 73 73 73 73 73 100 100 66 67 68 69 70 100 100 73 73 73 67 106", "StartB a Latch é (5) Unlatch b c d e f Latch é (3)" },
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = sizeof(data) / sizeof(struct item);
@ -65,15 +278,24 @@ static void test_input(int index, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology; symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
symbol->input_mode = data[i].input_mode;
symbol->debug |= debug;
int length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length; int 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);
ret = ZBarcode_Encode(symbol, data[i].data, length); ret = ZBarcode_Encode(symbol, 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 (generate) {
printf(" /*%3d*/ { %s, \"%s\", %d, %s, %d, \"%s\", \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length,
testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment);
} else {
if (ret < 5) {
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);
}
}
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
} }
@ -88,7 +310,6 @@ static void test_encode(int index, int generate, int debug) {
struct item { struct item {
int symbology; int symbology;
int input_mode; int input_mode;
int output_options;
unsigned char *data; unsigned char *data;
int ret; int ret;
@ -97,22 +318,83 @@ static void test_encode(int index, int generate, int debug) {
char *comment; char *comment;
char *expected; char *expected;
}; };
// BARCODE_EAN128 examples verified manually against GS1 General Specifications 20.0
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_CODE128, UNICODE_MODE, -1, "AIM", 0, 1, 68, "ISO/IEC 15417:2007 Figure 1", /* 0*/ { BARCODE_CODE128, UNICODE_MODE, "AIM", 0, 1, 68, "ISO/IEC 15417:2007 Figure 1",
"11010010000101000110001100010001010111011000101110110001100011101011" "11010010000101000110001100010001010111011000101110110001100011101011"
}, },
/* 1*/ { BARCODE_CODE128B, UNICODE_MODE, -1, "AIM", 0, 1, 68, "128B same", /* 1*/ { BARCODE_CODE128B, UNICODE_MODE, "AIM", 0, 1, 68, "128B same",
"11010010000101000110001100010001010111011000101110110001100011101011" "11010010000101000110001100010001010111011000101110110001100011101011"
}, },
/* 2*/ { BARCODE_CODE128, UNICODE_MODE, 16, "AIM", 0, 1, 79, "READER_INIT", /* 2*/ { BARCODE_CODE128, UNICODE_MODE, "1234567890", 0, 1, 90, "",
"1101001000010111100010101000110001100010001010111011000111010110001100011101011"
},
/* 3*/ { BARCODE_CODE128, UNICODE_MODE, -1, "1234567890", 0, 1, 90, "",
"110100111001011001110010001011000111000101101100001010011011110110100111100101100011101011" "110100111001011001110010001011000111000101101100001010011011110110100111100101100011101011"
}, },
/* 4*/ { BARCODE_CODE128B, UNICODE_MODE, -1, "1234567890", 0, 1, 145, "", /* 3*/ { BARCODE_CODE128B, UNICODE_MODE, "1234567890", 0, 1, 145, "",
"1101001000010011100110110011100101100101110011001001110110111001001100111010011101101110111010011001110010110010011101100101000110001100011101011" "1101001000010011100110110011100101100101110011001001110110111001001100111010011101101110111010011001110010110010011101100101000110001100011101011"
}, },
/* 4*/ { BARCODE_EAN128, GS1_MODE, "[8018]950110153123456781", 0, 1, 167, "GS1 General Specifications Figure 2.5.2-1",
"11010011100111101011101010011110011001110010101111010001100110110011001000100101110011001101100011011101101110101110110001000010110010010111100101111001001100011101011"
},
/* 5*/ { BARCODE_EAN128, GS1_MODE, "[415]5412345678908[3911]710125", 0, 1, 189, "GS1 General Specifications Figure 2.6.6-1 top",
"110100111001111010111011000100010111010001101100010001011101101110101110110001000010110011011011110100011001001101000100011000100100100110100001100110110011100101100100001001101100011101011"
},
/* 6*/ { BARCODE_EAN128, GS1_MODE, "[12]010425[8020]ABC123", 0, 1, 189, "GS1 General Specifications Figure 2.6.6-1 bottom",
"110100111001111010111010110011100110011011001001000110011100101100101001111001100100111010111101110101000110001000101100010001000110100111001101100111001011001011100110010111001100011101011"
},
/* 7*/ { BARCODE_EAN128, GS1_MODE, "[253]950110153005812345678901", 0, 1, 211, "GS1 General Specifications Figure 2.6.9-1",
"1101001110011110101110111001011001101000100011000101110110001001001100110110011011101110110110011001110110001010110011100100010110001110001011011000010100110111101101011110111010011100110101110110001100011101011"
},
/* 8*/ { BARCODE_EAN128, GS1_MODE, "[253]950110153006567890543210987", 0, 1, 211, "GS1 General Specifications Figure 2.6.9-2",
"1101001110011110101110111001011001101000100011000101110110001001001100110110011011101110110110011001001011000010000101100110110111101000100110010110001110110111001001100100100011110010100101110011001100011101011"
},
/* 9*/ { BARCODE_EAN128, GS1_MODE, "[253]95011015300657654321", 0, 1, 189, "GS1 General Specifications Figure 2.6.9-3",
"110100111001111010111011100101100110100010001100010111011000100100110011011001101110111011011001100100101100001100101000011101011000110001101101011110111010011100110111001001101100011101011"
},
/* 10*/ { BARCODE_EAN128, GS1_MODE, "[253]9501101530065123456", 0, 1, 167, "GS1 General Specifications Figure 2.6.9-4",
"11010011100111101011101110010110011010001000110001011101100010010011001101100110111011101101100110010010110000101100111001000101100011100010110100011110101100011101011"
},
/* 11*/ { BARCODE_EAN128, GS1_MODE, "[01]10857674002017[10]1152KMB", 0, 1, 211, "GS1 General Specifications Figure 4.15.1-1",
"1101001110011110101110110011011001100100010010011110010110010100001000011001011011001100110010011101001110011011001000100110001001001101110001010111101110101100011101011101100010001011000100111001101100011101011"
},
/* 12*/ { BARCODE_EAN128, GS1_MODE, "[01]09501101530003", 0, 1, 134, "GS1 General Specifications Figure 5.1-3",
"11010011100111101011101100110110011001001000110001011101100010010011001101100110111011101101100110010010011000100110100001100011101011"
},
/* 13*/ { BARCODE_EAN128, GS1_MODE, "[00]395123451234567895", 0, 1, 156, "GS1 General Specifications Figure 5.4.2-1",
"110100111001111010111011011001100110100010001101110100011101101110101110110001011001110010001011000111000101101100001010010111101000101111000101100011101011"
},
/* 14*/ { BARCODE_EAN128, GS1_MODE, "[00]395011010013000129", 0, 1, 156, "GS1 General Specifications Figure 6.6.5-6",
"110100111001111010111011011001100110100010001100010111011000100100110011011001101100110010011011100110110011001100110110011100110010111101101101100011101011"
},
/* 15*/ { BARCODE_EAN128, GS1_MODE, "[401]931234518430GR", 0, 1, 167, "GS1 General Specifications Figure 6.6.5-7 top",
"11010011100111101011101100010100011001011100110110001101110110111010111011000110011100101011000111010111101110100111011001101000100011000101110100110111001100011101011"
},
/* 16*/ { BARCODE_EAN128, GS1_MODE, "[00]093123450000000012", 0, 1, 156, "GS1 General Specifications Figure 6.6.5-7 bottom",
"110100111001111010111011011001100110010010001101100011011101101110101110110001101100110011011001100110110011001101100110010110011100110111010001100011101011"
},
/* 17*/ { BARCODE_EAN128, GS1_MODE, "[01]95012345678903", 0, 1, 134, "GS1 General Specifications Figure 7.8.5.1-1 1st",
"11010011100111101011101100110110010111101000110011011001110110111010111011000100001011001101101111010010011000110110001101100011101011"
},
/* 18*/ { BARCODE_EAN128, GS1_MODE, "[3102]000400", 0, 1, 101, "GS1 General Specifications Figure 7.8.5.1-1 2nd",
"11010011100111101011101101100011011001100110110110011001001000110011011001100110110111101100011101011"
},
/* 19*/ { BARCODE_EAN128, GS1_MODE, "[01]95012345678903[3102]000400", 0, 1, 189, "GS1 General Specifications Figure 7.8.5.1-2",
"110100111001111010111011001101100101111010001100110110011101101110101110110001000010110011011011110100100110001101100011011001100110110110011001001000110011011001100100100110001100011101011"
},
/* 20*/ { BARCODE_EAN128, GS1_MODE, "[8005]000365", 0, 1, 101, "GS1 General Specifications Figure 7.8.5.2-1 1st",
"11010011100111101011101010011110010001001100110110011001001001100010010110000100100001101100011101011"
},
/* 21*/ { BARCODE_EAN128, GS1_MODE, "[10]123456", 0, 1, 90, "GS1 General Specifications Figure 7.8.5.2-1 2nd",
"110100111001111010111011001000100101100111001000101100011100010110110010000101100011101011"
},
/* 22*/ { BARCODE_EAN128, GS1_MODE, "[8005]000365[10]123456", 0, 1, 156, "GS1 General Specifications Figure 7.8.5.2-2",
"110100111001111010111010100111100100010011001101100110010010011000100101100001111010111011001000100101100111001000101100011100010110101100001001100011101011"
},
/* 23*/ { BARCODE_EAN14, GS1_MODE, "4070071967072", 0, 1, 134, "Verified manually against bwipp and tec-it",
"11010011100111101011101100110110011000101000101100001001001100010011001011100100001011001001100010011001001110110111001001100011101011"
},
/* 24*/ { BARCODE_NVE18, GS1_MODE, "40700000071967072", 0, 1, 156, "Verified manually against bwipp (sscc18) and tec-it",
"110100111001111010111011011001100110001010001011000010011011001100110110011001001100010011001011100100001011001001100010011001001110110111011101100011101011"
},
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = sizeof(data) / sizeof(struct item);
@ -125,24 +407,17 @@ static void test_encode(int index, int generate, int debug) {
struct zint_symbol *symbol = ZBarcode_Create(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology; int length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
symbol->input_mode = data[i].input_mode;
if (data[i].output_options != -1) {
symbol->output_options = data[i].output_options;
}
symbol->debug |= debug;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length); ret = ZBarcode_Encode(symbol, 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 (generate) { if (generate) {
printf(" /*%3d*/ { %s, %s, %d, \"%s\", %s, %d, %d, \"%s\",\n", printf(" /*%3d*/ { %s, %s, \"%s\", %s, %d, %d, \"%s\",\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].output_options, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment); testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n"); testUtilModulesDump(symbol, " ", "\n");
printf(" },\n"); printf(" },\n");
} else { } else {
if (ret < 5) { if (ret < 5) {
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->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
@ -165,7 +440,10 @@ static void test_encode(int index, int generate, int debug) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_input", test_input, 1, 0, 1 }, { "test_large", test_large, 1, 0, 1 },
{ "test_hrt", test_hrt, 1, 0, 1 },
{ "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
}; };

View File

@ -51,7 +51,7 @@ static void test_gs1_reduce(int index, int generate, int debug) {
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_EAN128, -1, "12345678901234", "", ZINT_ERROR_INVALID_DATA, "GS1 data required", "" }, /* 0*/ { BARCODE_EAN128, -1, "12345678901234", "", ZINT_ERROR_INVALID_DATA, "GS1 data required", "" },
/* 1*/ { BARCODE_EAN128, -1, "[01]12345678901234", "", 0, "Input mode ignored", /* 1*/ { BARCODE_EAN128, -1, "[01]12345678901234", "", 0, "Input mode ignored; verified manually against bwipp and tec-it",
"11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110010001011000111010111101100011101011" "11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110010001011000111010111101100011101011"
}, },
/* 2*/ { BARCODE_EAN128, GS1_MODE, "[01]12345678901234", "", 0, "Input mode ignored", /* 2*/ { BARCODE_EAN128, GS1_MODE, "[01]12345678901234", "", 0, "Input mode ignored",
@ -81,7 +81,7 @@ static void test_gs1_reduce(int index, int generate, int debug) {
"0010110001100001010001001100100110100110001101110100111000111010010011110101100100001001010011000110111010011100010100001011010000110011100010100" "0010110001100001010001001100100110100110001101110100111000111010010011110101100100001001010011000110111010011100010100001011010000110011100010100"
"1101001110011110101110110011011001011001110010001011000111000101101100001010011011110110101100111001000101100011101011110100101111001100011101011" "1101001110011110101110110011011001011001110010001011000111000101101100001010011011110110101100111001000101100011101011110100101111001100011101011"
}, },
/* 7*/ { BARCODE_EAN14, -1, "1234567890123", "", 0, "Input mode ignored", /* 7*/ { BARCODE_EAN14, -1, "1234567890123", "", 0, "Input mode ignored; verified manually against bwipp and tec-it",
"11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110011011000110100001100101100011101011" "11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110011011000110100001100101100011101011"
}, },
/* 8*/ { BARCODE_EAN14, GS1_MODE, "1234567890123", "", 0, "Input mode ignored", /* 8*/ { BARCODE_EAN14, GS1_MODE, "1234567890123", "", 0, "Input mode ignored",
@ -90,7 +90,7 @@ static void test_gs1_reduce(int index, int generate, int debug) {
/* 9*/ { BARCODE_EAN14, UNICODE_MODE, "1234567890123", "", 0, "Input mode ignored", /* 9*/ { BARCODE_EAN14, UNICODE_MODE, "1234567890123", "", 0, "Input mode ignored",
"11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110011011000110100001100101100011101011" "11010011100111101011101100110110010110011100100010110001110001011011000010100110111101101011001110011011000110100001100101100011101011"
}, },
/*10*/ { BARCODE_NVE18, -1, "12345678901234567", "", 0, "Input mode ignored", /*10*/ { BARCODE_NVE18, -1, "12345678901234567", "", 0, "Input mode ignored; verified manually against bwipp (sscc18) and tec-it",
"110100111001111010111011011001100101100111001000101100011100010110110000101001101111011010110011100100010110001110001011011000010010101101110001100011101011" "110100111001111010111011011001100101100111001000101100011100010110110000101001101111011010110011100100010110001110001011011000010010101101110001100011101011"
}, },
/*11*/ { BARCODE_NVE18, GS1_MODE, "12345678901234567", "", 0, "Input mode ignored", /*11*/ { BARCODE_NVE18, GS1_MODE, "12345678901234567", "", 0, "Input mode ignored",
@ -228,12 +228,16 @@ static void test_hrt(int index, int debug) {
unsigned char *expected; unsigned char *expected;
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_EAN128, "[01]12345678901234[20]12", "", "(01)12345678901234(20)12" }, /* 0*/ { BARCODE_EAN128, "[01]12345678901234[20]12", "", "(01)12345678901234(20)12" },
/* 1*/ { BARCODE_EAN128_CC, "[01]12345678901234[20]12", "[21]12345", "(01)12345678901234(20)12" }, /* 1*/ { BARCODE_EAN128_CC, "[01]12345678901234[20]12", "[21]12345", "(01)12345678901234(20)12" },
/* 2*/ { BARCODE_RSS_EXP, "[01]12345678901234[20]12", "", "(01)12345678901234(20)12" }, /* 2*/ { BARCODE_EAN14, "1234567890123", "", "(01)12345678901231" },
/* 3*/ { BARCODE_RSS_EXP_CC, "[01]12345678901234", "[21]12345", "(01)12345678901234" }, /* 3*/ { BARCODE_NVE18, "12345678901234567", "", "(00)123456789012345675" },
/* 4*/ { BARCODE_RSS_EXP, "[01]12345678901234[20]12", "", "(01)12345678901234(20)12" },
/* 5*/ { BARCODE_RSS_EXP_CC, "[01]12345678901234", "[21]12345", "(01)12345678901234" },
/* 6*/ { BARCODE_RSS_EXPSTACK, "[01]12345678901234[20]12", "", "" },
/* 7*/ { BARCODE_RSS_EXPSTACK_CC, "[01]12345678901234[20]12", "[21]12345", "" },
}; };
int data_size = sizeof(data) / sizeof(struct item); int data_size = sizeof(data) / sizeof(struct item);

View File

@ -153,6 +153,60 @@ static void test_input_mode(int index, int debug) {
testFinish(); testFinish();
} }
static void test_escape_char_process(int index, int generate, int debug) {
testStart("");
int ret;
struct item {
unsigned char *data;
int ret;
int expected_width;
char *expected;
char *comment;
};
struct item data[] = {
/* 0*/ { "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 200, "(18) 103 64 68 71 72 73 74 75 76 77 91 93 94 101 65 60 44 106", "" },
/* 1*/ { "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character in input data", "" },
/* 2*/ { "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", "" },
/* 3*/ { "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", "" },
/* 4*/ { "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", "" },
/* 5*/ { "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Corrupt escape character in input data", "" },
};
int data_size = ARRAY_SIZE(data);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = testUtilSetSymbol(symbol, BARCODE_CODE128, DATA_MODE | ESCAPE_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, 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);
if (generate) {
printf(" /*%3d*/ { \"%s\", %s, %d, \"%s\", \"%s\" },\n",
i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment);
} else {
if (ret < 5) {
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);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
// #181 Nico Gunkel OSS-Fuzz // #181 Nico Gunkel OSS-Fuzz
static void test_encode_file_zero_length(void) { static void test_encode_file_zero_length(void) {
@ -210,6 +264,7 @@ int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_checks", test_checks, 1, 0, 1 }, { "test_checks", test_checks, 1, 0, 1 },
{ "test_input_mode", test_input_mode, 1, 0, 1 }, { "test_input_mode", test_input_mode, 1, 0, 1 },
{ "test_escape_char_process", test_escape_char_process, 1, 1, 1 },
{ "test_encode_file_zero_length", test_encode_file_zero_length, 0, 0, 0 }, { "test_encode_file_zero_length", test_encode_file_zero_length, 0, 0, 0 },
{ "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 }, { "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 },
}; };

View File

@ -31,6 +31,11 @@
#include "testcommon.h" #include "testcommon.h"
static int is_row_column_black(struct zint_symbol *symbol, int row, int column) {
int i = (row * symbol->bitmap_width + column) * 3;
return symbol->bitmap[i] == 0 && symbol->bitmap[i + 1] == 0 && symbol->bitmap[i + 2] == 0; // Black
}
static void test_chk_extendable(int index, int debug) { static void test_chk_extendable(int index, int debug) {
testStart(""); testStart("");
@ -87,8 +92,7 @@ static void test_chk_extendable(int index, int debug) {
int addon_text_bits_set = 0; int addon_text_bits_set = 0;
int row = data[i].expected_addon_text_row; int row = data[i].expected_addon_text_row;
for (int column = data[i].expected_addon_text_col; column < data[i].expected_addon_text_col + 48; column++) { for (int column = data[i].expected_addon_text_col; column < data[i].expected_addon_text_col + 48; column++) {
int j = (row * symbol->bitmap_width + column) * 3; if (is_row_column_black(symbol, row, column)) {
if (symbol->bitmap[j] == 0 && symbol->bitmap[j + 1] == 0 && symbol->bitmap[j + 2] == 0) { // Black
addon_text_bits_set = 1; addon_text_bits_set = 1;
break; break;
} }
@ -105,10 +109,83 @@ static void test_chk_extendable(int index, int debug) {
testFinish(); testFinish();
} }
static void test_row_separator(int index, int debug) {
testStart("");
int ret;
struct item {
int symbology;
int option_3;
unsigned char *data;
int ret;
int expected_height;
int expected_rows;
int expected_width;
int expected_bitmap_width;
int expected_bitmap_height;
int expected_separator_row;
int expected_separator_col;
int expected_separator_height;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_CODABLOCKF, -1, "A", 0, 20, 2, 101, 210, 48, 22, 28, 4 }, // Col 28 TODO: investigate extra 2 compared to vector 26
/* 1*/ { BARCODE_CODABLOCKF, 0, "A", 0, 20, 2, 101, 210, 48, 22, 28, 4 }, // Same as default
/* 2*/ { BARCODE_CODABLOCKF, 1, "A", 0, 20, 2, 101, 210, 48, 23, 28, 2 },
/* 3*/ { BARCODE_CODABLOCKF, 2, "A", 0, 20, 2, 101, 210, 48, 22, 28, 4 }, // Same as default
/* 4*/ { BARCODE_CODABLOCKF, 3, "A", 0, 20, 2, 101, 210, 48, 21, 28, 6 },
/* 5*/ { BARCODE_CODABLOCKF, 4, "A", 0, 20, 2, 101, 210, 48, 20, 28, 8 },
/* 6*/ { BARCODE_CODABLOCKF, 5, "A", 0, 20, 2, 101, 210, 48, 22, 28, 4 }, // > 4 ignored, same as default
};
int data_size = ARRAY_SIZE(data);
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode_and_Buffer(symbol, data[i].data, length, 0);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
assert_nonnull(symbol->bitmap, "i:%d (%d) symbol->bitmap NULL\n", i, data[i].symbology);
assert_equal(symbol->height, data[i].expected_height, "i:%d (%d) symbol->height %d != %d\n", i, data[i].symbology, symbol->height, data[i].expected_height);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%d) symbol->rows %d != %d\n", i, data[i].symbology, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d (%d) symbol->width %d != %d\n", i, data[i].symbology, symbol->width, data[i].expected_width);
assert_equal(symbol->bitmap_width, data[i].expected_bitmap_width, "i:%d (%d) symbol->bitmap_width %d != %d\n", i, data[i].symbology, symbol->bitmap_width, data[i].expected_bitmap_width);
assert_equal(symbol->bitmap_height, data[i].expected_bitmap_height, "i:%d (%d) symbol->bitmap_height %d != %d\n", i, data[i].symbology, symbol->bitmap_height, data[i].expected_bitmap_height);
int j, separator_bits_set;
for (j = data[i].expected_separator_row; j < data[i].expected_separator_row + data[i].expected_separator_height; j++) {
separator_bits_set = is_row_column_black(symbol, j, data[i].expected_separator_col);
assert_nonzero(separator_bits_set, "i:%d (%d) separator_bits_set (%d, %d) zero\n", i, data[i].symbology, j, data[i].expected_separator_col);
}
j = data[i].expected_separator_row - 1;
separator_bits_set = is_row_column_black(symbol, j, data[i].expected_separator_col);
assert_zero(separator_bits_set, "i:%d (%d) separator_bits_set (%d, %d) before non-zero\n", i, data[i].symbology, j, data[i].expected_separator_col);
j = data[i].expected_separator_row + data[i].expected_separator_height;
separator_bits_set = is_row_column_black(symbol, j, data[i].expected_separator_col);
assert_zero(separator_bits_set, "i:%d (%d) separator_bits_set (%d, %d) after non-zero\n", i, data[i].symbology, j, data[i].expected_separator_col);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_chk_extendable", test_chk_extendable, 1, 0, 1 }, { "test_chk_extendable", test_chk_extendable, 1, 0, 1 },
{ "test_row_separator", test_row_separator, 1, 0, 1 },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));

View File

@ -31,6 +31,35 @@
#include "testcommon.h" #include "testcommon.h"
static struct zint_vector_rect *find_rect(struct zint_symbol *symbol, int x, int y, int height, int width) {
struct zint_vector_rect *rect;
if (symbol->vector == NULL) {
return NULL;
}
for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
if (rect->x == x && rect->y == y) {
if (height && width) {
if (rect->height == height && rect->width == width) {
break;
}
} else if (height) {
if (rect->height == height) {
break;
}
} else if (width) {
if (rect->width == width) {
break;
}
} else {
break;
}
}
}
return rect;
}
static void test_buffer_vector(int index, int generate, int debug) { static void test_buffer_vector(int index, int generate, int debug) {
testStart(""); testStart("");
@ -96,7 +125,7 @@ static void test_buffer_vector(int index, int generate, int debug) {
/* 45*/ { BARCODE_DATAMATRIX, "ABC", "", 10, 10, 10, 20.0, 20.0 }, /* 45*/ { BARCODE_DATAMATRIX, "ABC", "", 10, 10, 10, 20.0, 20.0 },
/* 46*/ { BARCODE_EAN14, "1234567890123", "", 50, 1, 134, 268.0, 118.0 }, /* 46*/ { BARCODE_EAN14, "1234567890123", "", 50, 1, 134, 268.0, 118.0 },
/* 47*/ { BARCODE_VIN, "00000000000000000", "", 50, 1, 246, 492.0, 118.0 }, /* 47*/ { BARCODE_VIN, "00000000000000000", "", 50, 1, 246, 492.0, 118.0 },
/* 48*/ { BARCODE_CODABLOCKF, "0000000000", "", 10, 1, 90, 188.0, 28.0 }, /* 48*/ { BARCODE_CODABLOCKF, "0000000000", "", 20, 2, 101, 210.0, 48.0 },
/* 49*/ { BARCODE_NVE18, "12345678901234567", "", 50, 1, 156, 312.0, 118.0 }, /* 49*/ { BARCODE_NVE18, "12345678901234567", "", 50, 1, 156, 312.0, 118.0 },
/* 50*/ { BARCODE_JAPANPOST, "0000000000", "", 8, 3, 133, 266.0, 16.0 }, /* 50*/ { BARCODE_JAPANPOST, "0000000000", "", 8, 3, 133, 266.0, 16.0 },
/* 51*/ { BARCODE_KOREAPOST, "123456", "", 50, 1, 167, 334.0, 118.0 }, /* 51*/ { BARCODE_KOREAPOST, "123456", "", 50, 1, 167, 334.0, 118.0 },
@ -119,7 +148,7 @@ static void test_buffer_vector(int index, int generate, int debug) {
/* 68*/ { BARCODE_HIBC_QR, "1234567890AB", "", 21, 21, 21, 42.0, 42.0 }, /* 68*/ { BARCODE_HIBC_QR, "1234567890AB", "", 21, 21, 21, 42.0, 42.0 },
/* 69*/ { BARCODE_HIBC_PDF, "0000000000", "", 27, 9, 103, 206.0, 54.0 }, /* 69*/ { BARCODE_HIBC_PDF, "0000000000", "", 27, 9, 103, 206.0, 54.0 },
/* 70*/ { BARCODE_HIBC_MICPDF, "0000000000", "", 34, 17, 38, 76.0, 68.0 }, /* 70*/ { BARCODE_HIBC_MICPDF, "0000000000", "", 34, 17, 38, 76.0, 68.0 },
/* 71*/ { BARCODE_HIBC_BLOCKF, "0000000000", "", 40, 4, 90, 188.0, 88.0 }, /* 71*/ { BARCODE_HIBC_BLOCKF, "0000000000", "", 30, 3, 101, 210.0, 68.0 },
/* 72*/ { BARCODE_HIBC_AZTEC, "1234567890AB", "", 19, 19, 19, 38.0, 38.0 }, /* 72*/ { BARCODE_HIBC_AZTEC, "1234567890AB", "", 19, 19, 19, 38.0, 38.0 },
/* 73*/ { BARCODE_DOTCODE, "ABC", "", 11, 11, 16, 32.0, 22.0 }, /* 73*/ { BARCODE_DOTCODE, "ABC", "", 11, 11, 16, 32.0, 22.0 },
/* 74*/ { BARCODE_HANXIN, "1234567890AB", "", 23, 23, 23, 46.0, 46.0 }, /* 74*/ { BARCODE_HANXIN, "1234567890AB", "", 23, 23, 23, 46.0, 46.0 },
@ -311,12 +340,74 @@ static void test_upcean_whitespace_width(int index, int debug) {
testFinish(); testFinish();
} }
static void test_row_separator(int index, int debug) {
testStart("");
int ret;
struct item {
int symbology;
int option_3;
unsigned char *data;
int ret;
int expected_height;
int expected_rows;
int expected_width;
int expected_separator_row;
int expected_separator_col;
int expected_separator_height;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_CODABLOCKF, -1, "A", 0, 20, 2, 101, 22, 26, 4 },
/* 1*/ { BARCODE_CODABLOCKF, 0, "A", 0, 20, 2, 101, 22, 26, 4 }, // Same as default
/* 2*/ { BARCODE_CODABLOCKF, 1, "A", 0, 20, 2, 101, 23, 26, 2 },
/* 3*/ { BARCODE_CODABLOCKF, 2, "A", 0, 20, 2, 101, 22, 26, 4 }, // Same as default
/* 4*/ { BARCODE_CODABLOCKF, 3, "A", 0, 20, 2, 101, 21, 26, 6 },
/* 5*/ { BARCODE_CODABLOCKF, 4, "A", 0, 20, 2, 101, 20, 26, 8 },
/* 6*/ { BARCODE_CODABLOCKF, 5, "A", 0, 20, 2, 101, 22, 26, 4 }, // > 4 ignored, same as default
};
int data_size = ARRAY_SIZE(data);
struct zint_vector_rect *rect;
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_zero(ret, "i:%d ZBarcode_Encode(%d) ret %d != 0 %s\n", i, data[i].symbology, ret, symbol->errtxt);
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_zero(ret, "i:%d ZBarcode_Buffer_Vector(%d) ret %d != 0\n", i, data[i].symbology, ret);
assert_nonnull(symbol->vector, "i:%d ZBarcode_Buffer_Vector(%d) vector NULL\n", i, data[i].symbology);
assert_equal(symbol->height, data[i].expected_height, "i:%d (%d) symbol->height %d != %d\n", i, data[i].symbology, symbol->height, data[i].expected_height);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d (%d) symbol->rows %d != %d\n", i, data[i].symbology, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d (%d) symbol->width %d != %d\n", i, data[i].symbology, symbol->width, data[i].expected_width);
rect = find_rect(symbol, data[i].expected_separator_col, data[i].expected_separator_row, data[i].expected_separator_height, 0);
assert_nonnull(rect, "i:%d (%d) find_rect(%d, %d, %d) NULL\n", i, data[i].symbology, data[i].expected_separator_col, data[i].expected_separator_row, data[i].expected_separator_height);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_buffer_vector", test_buffer_vector, 1, 1, 1 }, { "test_buffer_vector", test_buffer_vector, 1, 1, 1 },
{ "test_noncomposite_string_x", test_noncomposite_string_x, 1, 0, 1 }, { "test_noncomposite_string_x", test_noncomposite_string_x, 1, 0, 1 },
{ "test_upcean_whitespace_width", test_upcean_whitespace_width, 1, 0, 1 }, { "test_upcean_whitespace_width", test_upcean_whitespace_width, 1, 0, 1 },
{ "test_row_separator", test_row_separator, 1, 0, 1 },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));

View File

@ -389,6 +389,34 @@ char *testUtilBarcodeName(int symbology) {
return data[symbology].name; return data[symbology].name;
} }
int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, int option_1, int option_2, int option_3, int output_options, char *data, int length, int debug) {
symbol->symbology = symbology;
if (input_mode != -1) {
symbol->input_mode = input_mode;
}
if (eci != -1) {
symbol->eci = eci;
}
if (option_1 != -1) {
symbol->option_1 = option_1;
}
if (option_2 != -1) {
symbol->option_2 = option_2;
}
if (option_3 != -1) {
symbol->option_3 = option_3;
}
if (output_options != -1) {
symbol->output_options = output_options;
}
symbol->debug |= debug;
if (length == -1) {
length = strlen(data);
}
return length;
}
char *testUtilErrorName(int error_number) { char *testUtilErrorName(int error_number) {
struct item { struct item {
int define; int define;
@ -499,9 +527,9 @@ int testUtilIsValidUTF8(const unsigned char str[], const size_t length) {
char *testUtilEscape(char *buffer, int length, char *escaped, int escaped_size) { char *testUtilEscape(char *buffer, int length, char *escaped, int escaped_size) {
int i; int i;
unsigned char *b = buffer; unsigned char *b = (unsigned char *) buffer;
unsigned char *be = buffer + length; unsigned char *be = b + length;
int non_utf8 = !testUtilIsValidUTF8(buffer, length); int non_utf8 = !testUtilIsValidUTF8(b, length);
for (i = 0; b < be && i < escaped_size; b++) { for (i = 0; b < be && i < escaped_size; b++) {
if (non_utf8 || *b < ' ' || *b == '\177') { if (non_utf8 || *b < ' ' || *b == '\177') {

View File

@ -72,6 +72,7 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size);
extern void vector_free(struct zint_symbol *symbol); /* Free vector structures */ extern void vector_free(struct zint_symbol *symbol); /* Free vector structures */
int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, int option_1, int option_2, int option_3, int output_options, char *data, int length, int debug);
char *testUtilBarcodeName(int symbology); char *testUtilBarcodeName(int symbology);
char *testUtilErrorName(int error_number); char *testUtilErrorName(int error_number);
char *testUtilInputModeName(int input_mode); char *testUtilInputModeName(int input_mode);

View File

@ -785,14 +785,19 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
// Binding and boxes // Binding and boxes
if ((symbol->output_options & BARCODE_BIND) != 0) { if ((symbol->output_options & BARCODE_BIND) != 0) {
if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
double sep_height = 2;
if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
sep_height = symbol->option_3;
}
/* row binding */ /* row binding */
for (r = 1; r < symbol->rows; r++) { for (r = 1; r < symbol->rows; r++) {
if (symbol->symbology != BARCODE_CODABLOCKF) { if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
rectangle = vector_plot_create_rect((float)xoffset, (r * row_height) + yoffset - 1, (float)symbol->width, 2.0f); rectangle = vector_plot_create_rect((float)xoffset, (r * row_height) + yoffset - sep_height / 2, (float)symbol->width, sep_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle); vector_plot_add_rect(symbol, rectangle, &last_rectangle);
} else { } else {
/* Avoid 11-module start and stop chars */ /* Avoid 11-module start and stop chars */
rectangle = vector_plot_create_rect(xoffset + 11, (r * row_height) + yoffset - 1, symbol->width - 22, 2.0); rectangle = vector_plot_create_rect(xoffset + 11, (r * row_height) + yoffset - sep_height / 2, symbol->width - 22, sep_height);
vector_plot_add_rect(symbol, rectangle, &last_rectangle); vector_plot_add_rect(symbol, rectangle, &last_rectangle);
} }
} }
@ -801,14 +806,14 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_
if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
// Top // Top
rectangle = vector_plot_create_rect(0.0f, 0.0f, vector->width, (float)symbol->border_width); rectangle = vector_plot_create_rect(0.0f, 0.0f, vector->width, (float)symbol->border_width);
if (symbol->symbology == BARCODE_CODABLOCKF) { if (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF) {
rectangle->x = (float)xoffset; rectangle->x = (float)xoffset;
rectangle->width -= (2.0f * xoffset); rectangle->width -= (2.0f * xoffset);
} }
vector_plot_add_rect(symbol, rectangle, &last_rectangle); vector_plot_add_rect(symbol, rectangle, &last_rectangle);
// Bottom // Bottom
rectangle = vector_plot_create_rect(0.0f, vector->height - symbol->border_width - text_offset, vector->width, (float)symbol->border_width); rectangle = vector_plot_create_rect(0.0f, vector->height - symbol->border_width - text_offset, vector->width, (float)symbol->border_width);
if (symbol->symbology == BARCODE_CODABLOCKF) { if (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF) {
rectangle->x = (float)xoffset; rectangle->x = (float)xoffset;
rectangle->width -= (2.0f * xoffset); rectangle->width -= (2.0f * xoffset);
} }

View File

@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/
/* vim: set ts=4 sw=4 et : */
#include "qzint.h" #include "qzint.h"
#include <stdio.h> #include <stdio.h>
@ -71,7 +72,7 @@ namespace Zint {
} else { } else {
m_zintSymbol->show_hrt = 1; m_zintSymbol->show_hrt = 1;
} }
m_zintSymbol->option_3 = m_option_3; m_zintSymbol->option_3 = m_option_3;
QByteArray bstr = m_text.toUtf8(); QByteArray bstr = m_text.toUtf8();
QByteArray pstr = m_primaryMessage.left(99).toLatin1(); QByteArray pstr = m_primaryMessage.left(99).toLatin1();
strcpy(m_zintSymbol->primary, pstr.data()); strcpy(m_zintSymbol->primary, pstr.data());
@ -236,7 +237,7 @@ namespace Zint {
} else { } else {
m_zintSymbol->show_hrt = 1; m_zintSymbol->show_hrt = 1;
} }
m_zintSymbol->option_3 = m_option_3; m_zintSymbol->option_3 = m_option_3;
m_zintSymbol->scale = m_scale; m_zintSymbol->scale = m_scale;
QByteArray bstr = m_text.toUtf8(); QByteArray bstr = m_text.toUtf8();
QByteArray pstr = m_primaryMessage.left(99).toLatin1(); QByteArray pstr = m_primaryMessage.left(99).toLatin1();
@ -263,6 +264,8 @@ namespace Zint {
struct zint_vector_string *string; struct zint_vector_string *string;
qreal radius; qreal radius;
(void)mode; /* Not currently used */
encode(); encode();
QFont fontSmall(fontstyle); QFont fontSmall(fontstyle);

View File

@ -1545,18 +1545,25 @@ error = ZBarcode_Encode(my_symbol, "That");
error = ZBarcode_Print(my_symbol); error = ZBarcode_Print(my_symbol);
The stacked barcode rows can be separated by row separator bars by specifying
--bind (output_options |= BARCODE_BIND). The height of the row separator bars
in x-dimension multiples (default 2, minimum 1, maximum 4) can be set by
--separator= (option_3):
zind --bind --separator=1 -d 'This' -d 'That'
A more sophisticated method is to use some type of line indexing which indicates A more sophisticated method is to use some type of line indexing which indicates
to the barcode reader which order the symbols should be read. This is to the barcode reader which order the symbols should be read. This is
demonstrated by the symbologies below. demonstrated by the symbologies below.
6.2.2 Codablock-F 6.2.2 Codablock-F
----------------- -----------------
This is a stacked symbology based on Code 128 which can encode ASCII code set This is a stacked symbology based on Code 128 which can encode extended ASCII
data up to a maximum length of 2725 characters. The width of the Codablock-F code set data up to a maximum length of 2725 characters. The width of the
symbol can be set using the --cols= option at the command line or option_2. Codablock-F symbol can be set using the --cols= option at the command line or
Alternatively the height (number of rows) can be set using the --rows= option option_2. The height (number of rows) can be set using the --rows= option at the
at the command line or by setting option_1. Zint does not support encoding of command line or by setting option_1. Zint does not support encoding of GS1 data
GS1 data in Codablock-F symbols. in Codablock-F symbols.
6.2.3 Code 16k (EN 12323) 6.2.3 Code 16k (EN 12323)
------------------------- -------------------------

View File

@ -18,6 +18,7 @@
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -60,7 +61,7 @@ void types(void) {
"30: GS1 DataBar Ltd 79: GS1 DataBar Stack 136: Comp UPC-E\n" "30: GS1 DataBar Ltd 79: GS1 DataBar Stack 136: Comp UPC-E\n"
"31: GS1 DataBar ExpOm 80: GS1 DataBar Stack Omni 137: Comp DataBar Stack\n" "31: GS1 DataBar ExpOm 80: GS1 DataBar Stack Omni 137: Comp DataBar Stack\n"
"32: Telepen Alpha 81: GS1 DataBar ESO 138: Comp DataBar Stack Omni\n" "32: Telepen Alpha 81: GS1 DataBar ESO 138: Comp DataBar Stack Omni\n"
"34: UPC-A 82: Planet 1139: Comp DataBar ESO\n" "34: UPC-A 82: Planet 139: Comp DataBar ESO\n"
"35: UPC-A + Check 84: MicroPDF 140: Channel Code\n" "35: UPC-A + Check 84: MicroPDF 140: Channel Code\n"
"37: UPC-E 85: USPS OneCode 141: Code One\n" "37: UPC-E 85: USPS OneCode 141: Code One\n"
"38: UPC-E + Check 86: UK Plessey 142: Grid Matrix\n" "38: UPC-E + Check 86: UK Plessey 142: Grid Matrix\n"
@ -88,16 +89,16 @@ void usage(void) {
" --cols=NUMBER Set the number of data columns in symbol\n" " --cols=NUMBER Set the number of data columns in symbol\n"
" -d, --data=DATA Set the symbol content\n" " -d, --data=DATA Set the symbol content\n"
" --direct Send output to stdout\n" " --direct Send output to stdout\n"
" --dmre Allow Data Matrix Rectangular Extended\n"
" --dotsize=NUMBER Set radius of dots in dotty mode\n" " --dotsize=NUMBER Set radius of dots in dotty mode\n"
" --dotty Use dots instead of squares for matrix symbols\n" " --dotty Use dots instead of squares for matrix symbols\n"
" --dmre Allow Data Matrix Rectangular Extended\n"
" --dump Dump hexadecimal representation to stdout\n" " --dump Dump hexadecimal representation to stdout\n"
" -e, --ecinos Display table of ECI character encodings\n" " -e, --ecinos Display table of ECI character encodings\n"
" --eci=NUMBER Set the ECI mode for raw data\n" " --eci=NUMBER Set the ECI mode for raw data\n"
" --esc Process escape characters in input data\n" " --esc Process escape characters in input data\n"
" --filetype=TYPE Set output file type (PNG/EPS/SVG/PNG/EPS/GIF/TXT)\n"
" --fg=COLOUR Specify a foreground colour (in hex)\n" " --fg=COLOUR Specify a foreground colour (in hex)\n"
" --fullmultibyte Use multibyte mode for binary and Latin (QR Code/Han Xin/Grid Matrix)\n" " --filetype=TYPE Set output file type (PNG/EPS/SVG/PNG/EPS/GIF/TXT)\n"
" --fullmultibyte Use multibyte for binary/Latin (QR/Han Xin/Grid Matrix)\n"
" --gs1 Treat input as GS1 compatible data\n" " --gs1 Treat input as GS1 compatible data\n"
" --gssep Use separator GS for GS1\n" " --gssep Use separator GS for GS1\n"
" -h, --help Display help message\n" " -h, --help Display help message\n"
@ -109,8 +110,9 @@ void usage(void) {
" --notext Remove human readable text\n" " --notext Remove human readable text\n"
" -o, --output=FILE Send output to FILE. (default is out.png)\n" " -o, --output=FILE Send output to FILE. (default is out.png)\n"
" --primary=STRING Set structured primary message (Maxicode/Composite)\n" " --primary=STRING Set structured primary message (Maxicode/Composite)\n"
" --secure=NUMBER Set error correction level\n"
" --scale=NUMBER Adjust size of x-dimension\n" " --scale=NUMBER Adjust size of x-dimension\n"
" --secure=NUMBER Set error correction level\n"
" --separator=NUMBER Set height of row separator bars (stacked symbologies)\n"
" --small Use half-size text in PNG images\n" " --small Use half-size text in PNG images\n"
" --square Force Data Matrix symbols to be square\n" " --square Force Data Matrix symbols to be square\n"
" -r, --reverse Reverse colours (white on black)\n" " -r, --reverse Reverse colours (white on black)\n"
@ -380,17 +382,42 @@ int batch_process(struct zint_symbol *symbol, char *filename, int mirror_mode, c
} }
int is_fullmultibyte(struct zint_symbol* symbol) { int is_fullmultibyte(struct zint_symbol* symbol) {
switch (symbol->symbology) { switch (symbol->symbology) {
case BARCODE_QRCODE: case BARCODE_QRCODE:
case BARCODE_MICROQR: case BARCODE_MICROQR:
//case BARCODE_HIBC_QR: Note character set restricted to ASCII subset //case BARCODE_HIBC_QR: Note character set restricted to ASCII subset
//case BARCODE_UPNQR: Note does not use Kanji mode //case BARCODE_UPNQR: Note does not use Kanji mode
case BARCODE_RMQR: case BARCODE_RMQR:
case BARCODE_HANXIN: case BARCODE_HANXIN:
case BARCODE_GRIDMATRIX: case BARCODE_GRIDMATRIX:
return 1; return 1;
} }
return 0; return 0;
}
/* Indicates which symbologies can have row binding
* Note: if change this must also change version in backend/common.c */
int is_stackable(const int symbology) {
if (symbology < BARCODE_PDF417) {
return 1;
}
switch (symbology) {
case BARCODE_CODE128B:
case BARCODE_ISBNX:
case BARCODE_EAN14:
case BARCODE_NVE18:
case BARCODE_KOREAPOST:
case BARCODE_PLESSEY:
case BARCODE_TELEPEN_NUM:
case BARCODE_ITF14:
case BARCODE_CODE32:
case BARCODE_CODABLOCKF:
case BARCODE_HIBC_BLOCKF:
return 1;
}
return 0;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -400,7 +427,8 @@ int main(int argc, char **argv) {
int generated; int generated;
int batch_mode; int batch_mode;
int mirror_mode; int mirror_mode;
int fullmultibyte; int fullmultibyte;
int separator;
char filetype[4]; char filetype[4];
int i; int i;
@ -412,6 +440,7 @@ int main(int argc, char **argv) {
batch_mode = 0; batch_mode = 0;
mirror_mode = 0; mirror_mode = 0;
fullmultibyte = 0; fullmultibyte = 0;
separator = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
filetype[i] = '\0'; filetype[i] = '\0';
@ -450,6 +479,7 @@ int main(int argc, char **argv) {
{"mode", 1, 0, 0}, {"mode", 1, 0, 0},
{"primary", 1, 0, 0}, {"primary", 1, 0, 0},
{"scale", 1, 0, 0}, {"scale", 1, 0, 0},
{"separator", 1, 0, 0},
{"gs1", 0, 0, 0}, {"gs1", 0, 0, 0},
{"gssep", 0, 0, 0}, {"gssep", 0, 0, 0},
{"binary", 0, 0, 0}, {"binary", 0, 0, 0},
@ -547,6 +577,15 @@ int main(int argc, char **argv) {
my_symbol->scale = 1.0; my_symbol->scale = 1.0;
} }
} }
if (!strcmp(long_options[option_index].name, "separator")) {
separator = atoi(optarg);
if (separator < 0 || separator > 4) {
/* Negative and greater than 4 values are not permitted */
fprintf(stderr, "Warning 127: Invalid separator value\n");
fflush(stderr);
separator = 0;
}
}
if (!strcmp(long_options[option_index].name, "dotsize")) { if (!strcmp(long_options[option_index].name, "dotsize")) {
my_symbol->dot_size = (float) (atof(optarg)); my_symbol->dot_size = (float) (atof(optarg));
if (my_symbol->dot_size < 0.01) { if (my_symbol->dot_size < 0.01) {
@ -584,7 +623,7 @@ int main(int argc, char **argv) {
} }
if (!strcmp(long_options[option_index].name, "cols")) { if (!strcmp(long_options[option_index].name, "cols")) {
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 66)) { if ((atoi(optarg) >= 1) && (atoi(optarg) <= 67)) {
my_symbol->option_2 = atoi(optarg); my_symbol->option_2 = atoi(optarg);
} else { } else {
fprintf(stderr, "Warning 111: Number of columns out of range\n"); fprintf(stderr, "Warning 111: Number of columns out of range\n");
@ -681,7 +720,7 @@ int main(int argc, char **argv) {
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 100)) { if ((atoi(optarg) >= 0) && (atoi(optarg) <= 100)) {
my_symbol->fontsize = atoi(optarg); my_symbol->fontsize = atoi(optarg);
} else { } else {
fprintf(stderr, "Warning 125: Invalid font size\n"); fprintf(stderr, "Warning 126: Invalid font size\n");
fflush(stderr); fflush(stderr);
} }
} }
@ -728,9 +767,11 @@ int main(int argc, char **argv) {
strcat(my_symbol->outfile, "."); strcat(my_symbol->outfile, ".");
strcat(my_symbol->outfile, filetype); strcat(my_symbol->outfile, filetype);
} }
if (fullmultibyte && is_fullmultibyte(my_symbol)) { if (fullmultibyte && is_fullmultibyte(my_symbol)) {
my_symbol->option_3 = ZINT_FULL_MULTIBYTE; my_symbol->option_3 = ZINT_FULL_MULTIBYTE;
} } else if (separator && is_stackable(my_symbol->symbology)) {
my_symbol->option_3 = separator;
}
error_number = ZBarcode_Encode(my_symbol, (unsigned char*) optarg, strlen(optarg)); error_number = ZBarcode_Encode(my_symbol, (unsigned char*) optarg, strlen(optarg));
generated = 1; generated = 1;
if (error_number != 0) { if (error_number != 0) {
@ -754,9 +795,11 @@ int main(int argc, char **argv) {
break; break;
case 'i': /* Take data from file */ case 'i': /* Take data from file */
if (fullmultibyte && is_fullmultibyte(my_symbol)) { if (fullmultibyte && is_fullmultibyte(my_symbol)) {
my_symbol->option_3 = ZINT_FULL_MULTIBYTE; my_symbol->option_3 = ZINT_FULL_MULTIBYTE;
} } else if (separator && is_stackable(my_symbol->symbology)) {
my_symbol->option_3 = separator;
}
if (batch_mode == 0) { if (batch_mode == 0) {
error_number = ZBarcode_Encode_File(my_symbol, optarg); error_number = ZBarcode_Encode_File(my_symbol, optarg);
generated = 1; generated = 1;
@ -824,4 +867,3 @@ int main(int argc, char **argv) {
return error_number; return error_number;
} }

View File

@ -16,129 +16,337 @@
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="0"> <item row="0" column="0">
<widget class="QRadioButton" name="radCbfSetHeight"> <widget class="QLabel" name="labelWidth">
<property name="text"> <property name="text">
<string>Set Symbol Height (Rows)</string> <string>S&amp;ymbol Width (Columns)</string>
</property>
<property name="buddy">
<cstring>cmbCbfWidth</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="0" column="1">
<widget class="QRadioButton" name="radCbfSetWidth">
<property name="text">
<string>Set Symbol Width (Columns)</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="cmbCbfWidth"> <widget class="QComboBox" name="cmbCbfWidth">
<item> <item>
<property name="text"> <property name="text">
<string>6</string> <string>Default</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>7</string> <string>9 (4 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>8</string> <string>10 (5 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>9</string> <string>11 (6 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>10</string> <string>12 (7 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>11</string> <string>13 (8 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>12</string> <string>14 (9 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>13</string> <string>15 (10 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>14</string> <string>16 (11 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>15</string> <string>17 (12 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>16</string> <string>18 (13 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>17</string> <string>19 (14 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>18</string> <string>20 (15 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>19</string> <string>21 (16 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>20</string> <string>22 (17 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>21</string> <string>23 (18 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>22</string> <string>24 (19 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>23</string> <string>25 (20 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>24</string> <string>26 (21 data)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>25</string> <string>27 (22 data)</string>
</property>
</item>
<item>
<property name="text">
<string>28 (23 data)</string>
</property>
</item>
<item>
<property name="text">
<string>29 (24 data)</string>
</property>
</item>
<item>
<property name="text">
<string>30 (25 data)</string>
</property>
</item>
<item>
<property name="text">
<string>31 (26 data)</string>
</property>
</item>
<item>
<property name="text">
<string>32 (27 data)</string>
</property>
</item>
<item>
<property name="text">
<string>33 (28 data)</string>
</property>
</item>
<item>
<property name="text">
<string>34 (29 data)</string>
</property>
</item>
<item>
<property name="text">
<string>35 (30 data)</string>
</property>
</item>
<item>
<property name="text">
<string>36 (31 data)</string>
</property>
</item>
<item>
<property name="text">
<string>37 (32 data)</string>
</property>
</item>
<item>
<property name="text">
<string>38 (33 data)</string>
</property>
</item>
<item>
<property name="text">
<string>39 (34 data)</string>
</property>
</item>
<item>
<property name="text">
<string>40 (35 data)</string>
</property>
</item>
<item>
<property name="text">
<string>41 (36 data)</string>
</property>
</item>
<item>
<property name="text">
<string>42 (37 data)</string>
</property>
</item>
<item>
<property name="text">
<string>43 (38 data)</string>
</property>
</item>
<item>
<property name="text">
<string>44 (39 data)</string>
</property>
</item>
<item>
<property name="text">
<string>45 (40 data)</string>
</property>
</item>
<item>
<property name="text">
<string>46 (41 data)</string>
</property>
</item>
<item>
<property name="text">
<string>47 (42 data)</string>
</property>
</item>
<item>
<property name="text">
<string>48 (43 data)</string>
</property>
</item>
<item>
<property name="text">
<string>49 (44 data)</string>
</property>
</item>
<item>
<property name="text">
<string>50 (45 data)</string>
</property>
</item>
<item>
<property name="text">
<string>51 (46 data)</string>
</property>
</item>
<item>
<property name="text">
<string>52 (47 data)</string>
</property>
</item>
<item>
<property name="text">
<string>53 (48 data)</string>
</property>
</item>
<item>
<property name="text">
<string>54 (49 data)</string>
</property>
</item>
<item>
<property name="text">
<string>55 (50 data)</string>
</property>
</item>
<item>
<property name="text">
<string>56 (51 data)</string>
</property>
</item>
<item>
<property name="text">
<string>57 (52 data)</string>
</property>
</item>
<item>
<property name="text">
<string>58 (53 data)</string>
</property>
</item>
<item>
<property name="text">
<string>59 (54 data)</string>
</property>
</item>
<item>
<property name="text">
<string>60 (55 data)</string>
</property>
</item>
<item>
<property name="text">
<string>61 (56 data)</string>
</property>
</item>
<item>
<property name="text">
<string>62 (57 data)</string>
</property>
</item>
<item>
<property name="text">
<string>63 (58 data)</string>
</property>
</item>
<item>
<property name="text">
<string>64 (59 data)</string>
</property>
</item>
<item>
<property name="text">
<string>65 (60 data)</string>
</property>
</item>
<item>
<property name="text">
<string>66 (61 data)</string>
</property>
</item>
<item>
<property name="text">
<string>67 (62 data)</string>
</property> </property>
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="1" column="0">
<widget class="QLabel" name="labelHeight">
<property name="text">
<string>Symbo&amp;l Height (Rows)</string>
</property>
<property name="buddy">
<cstring>cmbCbfHeight</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbCbfHeight"> <widget class="QComboBox" name="cmbCbfHeight">
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item> <item>
<property name="text"> <property name="text">
<string>1</string> <string>1</string>
@ -264,29 +472,185 @@
<string>25</string> <string>25</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>26</string>
</property>
</item>
<item>
<property name="text">
<string>27</string>
</property>
</item>
<item>
<property name="text">
<string>28</string>
</property>
</item>
<item>
<property name="text">
<string>29</string>
</property>
</item>
<item>
<property name="text">
<string>30</string>
</property>
</item>
<item>
<property name="text">
<string>31</string>
</property>
</item>
<item>
<property name="text">
<string>32</string>
</property>
</item>
<item>
<property name="text">
<string>33</string>
</property>
</item>
<item>
<property name="text">
<string>34</string>
</property>
</item>
<item>
<property name="text">
<string>35</string>
</property>
</item>
<item>
<property name="text">
<string>36</string>
</property>
</item>
<item>
<property name="text">
<string>37</string>
</property>
</item>
<item>
<property name="text">
<string>38</string>
</property>
</item>
<item>
<property name="text">
<string>39</string>
</property>
</item>
<item>
<property name="text">
<string>40</string>
</property>
</item>
<item>
<property name="text">
<string>41</string>
</property>
</item>
<item>
<property name="text">
<string>42</string>
</property>
</item>
<item>
<property name="text">
<string>43</string>
</property>
</item>
<item>
<property name="text">
<string>44</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="2" column="0">
<widget class="QRadioButton" name="radCbfAutosize"> <widget class="QLabel" name="labelRowSeparatorHeight">
<property name="text"> <property name="text">
<string>Automatic Size</string> <string>Row Separator Height</string>
</property> </property>
<property name="checked"> <property name="buddy">
<bool>true</bool> <cstring>cmbCbfRowSepHeight</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1">
<widget class="QComboBox" name="cmbCbfRowSepHeight">
<item>
<property name="text">
<string>Default (2 X)</string>
</property>
</item>
<item>
<property name="text">
<string>1 X</string>
</property>
</item>
<item>
<property name="text">
<string>2 X</string>
</property>
</item>
<item>
<property name="text">
<string>3 X</string>
</property>
</item>
<item>
<property name="text">
<string>4 X</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
<item>
<widget class="QGroupBox" name="groupBoxEncodingMode">
<property name="title">
<string>Encoding Mode</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QRadioButton" name="radCbfStand">
<property name="text">
<string>Standard Mode</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radCbfHIBC">
<property name="text">
<string>HIBC Codabloc&amp;k-F Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>40</height> <height>43</height>
</size> </size>
</property> </property>
</spacer> </spacer>

View File

@ -13,6 +13,7 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/
/* vim: set ts=4 sw=4 et : */
#include <QDebug> #include <QDebug>
#include <QGraphicsScene> #include <QGraphicsScene>
@ -526,11 +527,11 @@ void MainWindow::change_options()
m_optionWidget=uiload.load(&file); m_optionWidget=uiload.load(&file);
file.close(); file.close();
tabMain->insertTab(1,m_optionWidget,tr("Codablock-F")); tabMain->insertTab(1,m_optionWidget,tr("Codablock-F"));
connect(m_optionWidget->findChild<QObject*>("radCbfAutosize"), SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radCbfSetWidth"), SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radCbfSetHeight"), SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbCbfWidth"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild<QObject*>("cmbCbfWidth"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbCbfHeight"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild<QObject*>("cmbCbfHeight"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbCbfRowSepHeight"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radCbfStand"), SIGNAL(clicked( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radCbfHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
} }
if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DATAMATRIX) if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DATAMATRIX)
@ -769,6 +770,7 @@ void MainWindow::update_preview()
{ {
int width = view->geometry().width(); int width = view->geometry().width();
int height = view->geometry().height(); int height = view->geometry().height();
int item_val;
//m_bc.ar=(Zint::QZint::AspectRatioMode)1; //m_bc.ar=(Zint::QZint::AspectRatioMode)1;
if(chkComposite->isChecked() == true) { if(chkComposite->isChecked() == true) {
@ -779,6 +781,7 @@ void MainWindow::update_preview()
} }
m_bc.bc.setSecurityLevel(0); m_bc.bc.setSecurityLevel(0);
m_bc.bc.setWidth(0); m_bc.bc.setWidth(0);
m_bc.bc.setOption3(0);
m_bc.bc.setInputMode(UNICODE_MODE); m_bc.bc.setInputMode(UNICODE_MODE);
m_bc.bc.setHideText(0); m_bc.bc.setHideText(0);
if(chkHRTHide->isChecked() == false) { if(chkHRTHide->isChecked() == false) {
@ -945,14 +948,27 @@ void MainWindow::update_preview()
m_bc.bc.setInputMode(GS1_MODE); m_bc.bc.setInputMode(GS1_MODE);
break; break;
case BARCODE_CODABLOCKF: case BARCODE_CODABLOCKF:
if (m_optionWidget->findChild<QRadioButton*>("radCbfHIBC")->isChecked()) {
m_bc.bc.setSymbol(BARCODE_HIBC_BLOCKF);
} else {
m_bc.bc.setSymbol(BARCODE_CODABLOCKF); m_bc.bc.setSymbol(BARCODE_CODABLOCKF);
if(m_optionWidget->findChild<QRadioButton*>("radCbfSetWidth")->isChecked()) }
m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbCbfWidth")->currentIndex() + 6); item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfWidth")->currentIndex();
// Height selection uses option 1 in zint_symbol if (item_val) {
if(m_optionWidget->findChild<QRadioButton*>("radCbfSetHeight")->isChecked()) m_bc.bc.setWidth(item_val - 1 + 9);
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbCbfHeight")->currentIndex() + 1); }
break; // Height selection uses option 1 in zint_symbol
item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfHeight")->currentIndex();
if (item_val) {
m_bc.bc.setSecurityLevel(item_val);
}
// Row separator height selection uses option 3 in zint_symbol
item_val = m_optionWidget->findChild<QComboBox*>("cmbCbfRowSepHeight")->currentIndex();
if (item_val) {
m_bc.bc.setOption3(item_val);
}
break;
case BARCODE_DATAMATRIX: case BARCODE_DATAMATRIX:
m_bc.bc.setSecurityLevel(1); m_bc.bc.setSecurityLevel(1);