1
0
mirror of https://github.com/woo-j/zint.git synced 2024-12-25 09:33:56 +03:00

New files

This commit is contained in:
gitlost 2019-09-01 21:09:47 +01:00
parent d76cdd615b
commit 251a7d99c4
13 changed files with 12397 additions and 0 deletions

View File

@ -0,0 +1,44 @@
# Copyright (C) 2019 Robin Stuart <rstuart114@gmail.com>
# Adapted from qrencode/tests/CMakeLists.txt
# Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
cmake_minimum_required (VERSION 3.9)
enable_testing()
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
set(ZINT_DEBUG FALSE CACHE BOOL "Set debug compile flag")
set(ZINT_SANITIZE FALSE CACHE BOOL "Set sanitize compile/link flags")
find_package (LibZint 2.6.3 REQUIRED)
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
if (ZINT_DEBUG)
add_compile_options("-g")
endif (ZINT_DEBUG)
if (ZINT_SANITIZE)
add_compile_options("-fsanitize=undefined")
add_compile_options("-fsanitize=address")
set (CMAKE_EXE_LINKER_FLAGS "-fsanitize=undefined -fsanitize=address")
endif (ZINT_SANITIZE)
endif ()
add_library(testcommon
testcommon.c testcommon.h)
target_link_libraries(testcommon ZINT::ZINT)
macro(zint_add_test test_name test_command)
set(ADDITIONAL_LIBS "${ARGN}" ${LIBRARY_FLAGS})
add_executable(${test_command} ${test_command}.c)
target_link_libraries(${test_command} testcommon ${ADDITIONAL_LIBS})
add_test(${test_name} ${test_command})
endmacro(zint_add_test)
zint_add_test(channel, test_channel)
zint_add_test(eci, test_eci)
zint_add_test(imail, test_imail)
zint_add_test(mailmark, test_mailmark)
zint_add_test(maxicode, test_maxicode)
zint_add_test(rss, test_rss)
zint_add_test(upcean, test_upcean)

View File

@ -0,0 +1,53 @@
# - Try to find the Zint barcode library
# Once done this will define
#
# LIBZINT_FOUND - System has Zint barcode
# LIBZINT_INCLUDE_DIRS - The Zint barcode include directory
# LIBZINT_LIBRARIES - The libraries needed to use Zint barcode
# LIBZINT_DEFINITIONS - Definitions needed to use Zint barcode
# LIBZINT_VERSION_STRING - the version of Zint barcode found
set (LIBZINT_DEFINITIONS "")
find_path (LIBZINT_INCLUDE_DIR NAMES zint.h)
find_library (LIBZINT_LIBRARY NAMES zint )
if (LIBZINT_LIBRARY AND LIBZINT_INCLUDE_DIR)
set (LIBZINT_INCLUDE_DIRS ${LIBZINT_INCLUDE_DIR})
set (LIBZINT_LIBRARIES ${LIBZINT_LIBRARY})
set (LIBZINT_DEFINITIONS "")
if (NOT TARGET ZINT::ZINT)
add_library (ZINT::ZINT UNKNOWN IMPORTED)
set_target_properties (ZINT::ZINT PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "${LIBZINT_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${LIBZINT_INCLUDE_DIRS}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${LIBZINT_LIBRARY}"
)
endif ()
endif ()
if (LIBZINT_INCLUDE_DIR AND EXISTS "${LIBZINT_INCLUDE_DIR}/zint.h")
file (STRINGS "${LIBZINT_INCLUDE_DIR}/zint.h" ZINT_MAJOR_H REGEX "^#define ZINT_VERSION_MAJOR *[0-9]*")
file (STRINGS "${LIBZINT_INCLUDE_DIR}/zint.h" ZINT_MINOR_H REGEX "^#define ZINT_VERSION_MINOR *[0-9]*")
file (STRINGS "${LIBZINT_INCLUDE_DIR}/zint.h" ZINT_MICRO_H REGEX "^#define ZINT_VERSION_RELEASE *[0-9]*")
string (REGEX REPLACE "^.*VERSION_MAJOR *([0-9]*)" "\\1" ZINT_MAJOR ${ZINT_MAJOR_H})
string (REGEX REPLACE "^.*VERSION_MINOR *([0-9]*)" "\\1" ZINT_MINOR ${ZINT_MINOR_H})
string (REGEX REPLACE "^.*VERSION_RELEASE *([0-9]*)" "\\1" ZINT_MICRO ${ZINT_MICRO_H})
set (LIBZINT_VERSION_STRING ${ZINT_MAJOR}.${ZINT_MINOR}.${ZINT_MICRO})
endif()
# handle the QUIETLY and REQUIRED arguments and set LIBZINT_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibZint
REQUIRED_VARS LIBZINT_LIBRARY LIBZINT_INCLUDE_DIR
VERSION_VAR LIBZINT_VERSION_STRING)
mark_as_advanced(LIBZINT_INCLUDE_DIR LIBZINT_LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
static void test_encode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int option_2;
int ret_encode;
float w;
float h;
int ret_render;
};
struct item data[] = {
/* 0*/ { "0", 0, 0, 100, 30, 1 },
/* 1*/ { "1", 1, 0, 100, 30, 1 },
/* 2*/ { "26", 2, 0, 100, 30, 1 },
/* 3*/ { "026", 3, 0, 100, 30, 1 },
/* 4*/ { "0026", 3, 0, 100, 30, 1 },
/* 5*/ { "1234", 3, ZINT_ERROR_INVALID_DATA, 100, 30, -1 },
/* 6*/ { "1234", 4, ZINT_ERROR_INVALID_DATA, 100, 30, -1 },
/* 7*/ { "292", 4, 0, 100, 30, 1 },
/* 8*/ { "1234", 5, 0, 100, 30, 1 },
/* 9*/ { "1234567", 0, 0, 100, 30, 1 },
/*10*/ { "576688", 7, 0, 100, 30, 1 },
/*11*/ { "576689", 7, ZINT_ERROR_INVALID_DATA, 100, 30, -1 },
/*12*/ { "1234567", 0, 0, 100, 30, 1 },
/*13*/ { "1234567", 8, 0, 100, 30, 1 },
/*14*/ { "7742863", 8, ZINT_ERROR_INVALID_DATA, 100, 30, -1 },
/*15*/ { "0000000", 2, 0, 100, 30, 1 },
/*16*/ { "12345678", 8, ZINT_ERROR_TOO_LONG, 100, 30, -1 },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_CHANNEL;
symbol->option_2 = data[i].option_2;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
if (data[i].ret_render != -1) {
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_encode();
testReport();
return 0;
}

193
backend/tests/test_eci.c Normal file
View File

@ -0,0 +1,193 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
static void test_bom(void)
{
testStart("");
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_QRCODE;
symbol->input_mode = UNICODE_MODE;
symbol->option_1 = 4;
symbol->option_2 = 1;
char data[] = "\xEF\xBB\xBF"; // U+FEFF BOM, with U+2039 (only in Windows pages)
int length = strlen(data);
char expected[] =
"111111100001001111111"
"100000101110101000001"
"101110100000101011101"
"101110100111101011101"
"101110100110101011101"
"100000101011001000001"
"111111101010101111111"
"000000001100100000000"
"000011110110101100010"
"010011011100000100001"
"111110110001011111000"
"000110000110001011100"
"000111110111100001011"
"000000001011001000111"
"111111101010111001010"
"100000101110101101010"
"101110101110001110101"
"101110100001100101001"
"101110100111111111100"
"100000100010011010111"
"111111100101101000101";
int ret;
ret = ZBarcode_Encode(symbol, data, length);
assert_equal(ret, ZINT_WARN_USES_ECI, "ZBarcode_Encode ret %d != ZINT_WARN_USES_ECI\n", ret);
assert_equal(symbol->eci, 21, "eci %d != 21\n", symbol->eci); // ECI 21 == Windows-1250
int width, height;
ret = testUtilModulesCmp(symbol, expected, &width, &height);
assert_equal(ret, 0, "testUtilModulesEqual ret %d != 0, width %d, height %d\n", ret, width, height);
ZBarcode_Delete(symbol);
testFinish();
}
static void test_iso_8859_16(void)
{
testStart("");
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_QRCODE;
symbol->input_mode = UNICODE_MODE;
char data[] = "Ț"; // U+021A only in ISO 8859-16
int length = strlen(data);
int ret;
ret = ZBarcode_Encode(symbol, data, length);
assert_equal(ret, ZINT_WARN_USES_ECI, "ZBarcode_Encode ret %d != ZINT_WARN_USES_ECI\n", ret);
assert_equal(symbol->eci, 18, "eci %d != 18\n", symbol->eci); // ECI 18 == ISO 8859-16
ZBarcode_Delete(symbol);
testFinish();
}
static void test_encode(void)
{
testStart("");
int ret;
struct item {
int symbology;
int input_mode;
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_render;
int expected_eci;
};
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), in Shift-JIS, in GB-2312/18030
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859), in Shift-JIS, in GB-2312/18030
// ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859), not in Shift-JIS, not in GB-2312/18030
// ກ U+0E81 Lao not in any ISO 8859 (or Windows page) or Shift-JIS or GB-2312/18030
struct item data[] = {
/* 0*/ { BARCODE_QRCODE, UNICODE_MODE, "", 0, 100, 30, 1, 3 },
/* 1*/ { BARCODE_QRCODE, UNICODE_MODE, "", 0, 100, 30, 1, 3 }, // Converts to Shift-JIS
/* 2*/ { BARCODE_QRCODE, UNICODE_MODE, "Aก", ZINT_WARN_USES_ECI, 100, 30, 1, 13 }, // ECI 13 == ISO 8859-11
/* 3*/ { BARCODE_QRCODE, UNICODE_MODE, "Aéβ", 0, 100, 30, 1, 3 }, // Converts to Shift-JIS
/* 4*/ { BARCODE_QRCODE, UNICODE_MODE, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
/* 5*/ { BARCODE_QRCODE, UNICODE_MODE, "Aກ", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
/* 6*/ { BARCODE_MICROQR, UNICODE_MODE, "", 0, 100, 30, 1, 3 },
/* 7*/ { BARCODE_MICROQR, UNICODE_MODE, "", 0, 100, 30, 1, 3 }, // Converts to Shift-JIS
/* 8*/ { BARCODE_MICROQR, UNICODE_MODE, "Aéβ", 0, 100, 30, 1, 3 }, // Converts to Shift-JIS
/* 9*/ { BARCODE_MICROQR, UNICODE_MODE, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/*10*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "", 0, 100, 30, 1, 3 },
/*11*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "", 0, 100, 30, 1, 3 }, // Converts to GB-2312
/*12*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "Aก", ZINT_WARN_USES_ECI, 100, 30, 1, 13 }, // ECI 13 == ISO 8859-11
/*13*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "Aéβ", 0, 100, 30, 1, 3 }, // Converts to GB-2312
/*14*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
/*15*/ { BARCODE_HANXIN, UNICODE_MODE, "", 0, 100, 30, 1, 3 },
/*16*/ { BARCODE_HANXIN, UNICODE_MODE, "", 0, 100, 30, 1, 3 }, // Converts to GB-18030
/*17*/ { BARCODE_HANXIN, UNICODE_MODE, "Aก", ZINT_WARN_USES_ECI, 100, 30, 1, 13 }, // ECI 13 == ISO 8859-11
/*18*/ { BARCODE_HANXIN, UNICODE_MODE, "Aéβ", 0, 100, 30, 1, 3 }, // Converts to GB-18030
/*19*/ { BARCODE_HANXIN, UNICODE_MODE, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
/*20*/ { BARCODE_UPNQR, UNICODE_MODE, "", 0, 100, 30, 1, 4 }, // ECI 4 == iSO 8859-2
/*21*/ { BARCODE_UPNQR, UNICODE_MODE, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/*22*/ { BARCODE_DATAMATRIX, UNICODE_MODE, "", 0, 100, 30, 1, 3 },
/*23*/ { BARCODE_DATAMATRIX, UNICODE_MODE, "", ZINT_WARN_USES_ECI, 100, 30, 1, 9 }, // ECI 9 == ISO 8859-7
/*24*/ { BARCODE_DATAMATRIX, UNICODE_MODE, "Aก", ZINT_WARN_USES_ECI, 100, 30, 1, 13 }, // ECI 13 == ISO 8859-11
/*25*/ { BARCODE_DATAMATRIX, UNICODE_MODE, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
/*26*/ { BARCODE_DATAMATRIX, UNICODE_MODE, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 1, 26 },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
symbol->input_mode = data[i].input_mode;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
if (data[i].ret_render != -1) {
assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci);
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_bom();
test_iso_8859_16();
test_encode();
testReport();
return 0;
}

130
backend/tests/test_imail.c Normal file
View File

@ -0,0 +1,130 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
* Intelligent Mail barcode Encoder Test Case Reference Set (csv file)
* Copyright (C) 2009 U.S. Postal Service
*/
#include "testcommon.h"
#define TEST_IMAIL_CSV_MAX 1000
static void test_csv(void)
{
testStart("");
FILE* fd = fopen("../data/uspsIMbEncoderTestCases.csv", "r");
assert_nonnull(fd, "open ../data/uspsIMbEncoderTestCases.csv");
char buffer[1024];
char id[10];
char tracking_code[50];
char routing_code[50];
char data[102];
char expected_daft[70];
char return_code[10];
char actual_daft[70];
int ret;
int i;
int lc = 0;
while (fgets(buffer, sizeof(buffer), fd) != NULL) {
lc++;
#ifdef TEST_IMAIL_CSV_MAX
if (lc > TEST_IMAIL_CSV_MAX) {
break;
}
#endif
id[0] = tracking_code[0] = routing_code[0] = expected_daft[0] = return_code[0] = '\0';
char* b = testUtilReadCSVField(buffer, id, sizeof(id));
assert_nonnull(b, "lc:%d id b == NULL", lc);
assert_equal(*b, ',', "lc:%d id *b %c != ','", lc, *b);
b = testUtilReadCSVField(++b, tracking_code, sizeof(tracking_code));
assert_nonnull(b, "lc:%d tracking_code b == NULL", lc);
assert_equal(*b, ',', "lc:%d tracking_code *b %c != ','", lc, *b);
b = testUtilReadCSVField(++b, routing_code, sizeof(routing_code));
assert_nonnull(b, "lc:%d routing_code b == NULL", lc);
assert_equal(*b, ',', "lc:%d routing_code *b %c != ','", lc, *b);
b = testUtilReadCSVField(++b, expected_daft, sizeof(expected_daft));
assert_nonnull(b, "lc:%d expected_daft b == NULL", lc);
assert_equal(*b, ',', "lc:%d expected_daft *b %c != ','", lc, *b);
b = testUtilReadCSVField(++b, return_code, sizeof(return_code));
assert_nonnull(b, "lc:%d return_code b == NULL", lc);
assert_equal(*b, ',', "lc:%d return_code *b %c != ','", lc, *b);
strcpy(data, tracking_code);
strcat(data, "-");
strcat(data, routing_code);
assert_nonzero(strlen(data), "lc:%d strlen(data) == 0", lc);
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_ONECODE;
ret = ZBarcode_Encode(symbol, data, strlen(data));
if (strcmp(return_code, "00") == 0) {
assert_zero(ret, "lc:%d ZBarcode_Encode ret %d != 0\n", lc, ret);
assert_equal(symbol->rows, 3, "rows %d != 3", symbol->rows);
ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft));
assert_nonzero(ret, "lc:%d testUtilDAFTConvert == 0", lc);
assert_zero(strcmp(actual_daft, expected_daft), "lc:%d\n actual %s\nexpected %s\n", lc, actual_daft, expected_daft);
} else {
assert_nonzero(ret, "lc:%d ZBarcode_Encode ret %d == 0\n", lc, ret);
}
ZBarcode_Delete(symbol);
}
fclose(fd);
testFinish();
}
int main()
{
test_csv();
testReport();
return 0;
}

View File

@ -0,0 +1,91 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
static void test_encode_render(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_render;
unsigned char* expected_daft;
};
struct item data[] = {
/* 0*/ { "0100000000000AA000AA0A", 0, 100, 30, 1, "TFATTADAAATAFAFADFTAFATDTTDTTAAFTTFFTTDFTTFFTTAFADFDFAAFTDDFDADDAA" },
/* 1*/ { "0100000000009JA500AA0A", 0, 100, 30, 1, "TAFTTDADATTFDTFDFDFDTAATADADTTTATTFTDDDDTATDATDFTFFATAFFAFADAFFTDT" },
/* 2*/ { "1100000000000XY11 ", 0, 100, 30, 1, "TTDTTATTDTAATTDTAATTDTAATTDTTDDAATAADDATAATDDFAFTDDTAADDDTAAFDFAFF" },
/* 3*/ { "21B2254800659JW5O9QA6Y", 0, 100, 30, 1, "DAATATTTADTAATTFADDDDTTFTFDDDDFFDFDAFTADDTFFTDDATADTTFATTDAFDTFDDA" },
/* 4*/ { "11000000000000000XY11 ", 0, 100, 30, 1, "TTDTTATDDTTATTDTAATTDTAATDDTTATTDTTDATFTAATDDTAATDDTATATFAADDAATAATDDTAADFTFTA" },
/* 5*/ { "41038422416563762EF61AH8T", 0, 100, 30, 1, "DTTFATTDDTATTTATFTDFFFTFDFDAFTTTADTTFDTFDDDTDFDDFTFAADTFDTDTDTFAATAFDDTAATTDTT" },
};
int data_size = sizeof(data) / sizeof(struct item);
char actual_daft[80];
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_MAILMARK;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
assert_equal(symbol->rows, 3, "i:%d symbol->rows %d != 3\n", i, symbol->rows);
ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft));
assert_nonzero(ret, "i:%d testUtilDAFTConvert ret == 0", i);
assert_zero(strcmp(actual_daft, data[i].expected_daft), "i:%d\n actual %s\nexpected %s\n", i, actual_daft, data[i].expected_daft);
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_encode_render();
testReport();
return 0;
}

View File

@ -0,0 +1,134 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <zint.h>
#include "testcommon.h"
//#define TEST_RSS_GENERATE_EXPECTED 1
static void test_best_supported_set(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
int ret;
float w;
float h;
int ret_render;
int expected_rows;
int expected_width;
unsigned char* expected;
};
struct item data[] = {
/* 0*/ { BARCODE_MAXICODE, "am.//ab,\x1CTA# z\r!", 0, 100, 100, 1, 33, 30, // TODO: Better data and verify expected
"111010000101111000111101010111"
"111110000000010100111000000000"
"110000101100110100111010101011"
"010101010101010101010101010100"
"000000000000000000000000000000"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000000"
"101010101010101010101010101011"
"010101010111001100000101010110"
"000000001011000010000000000010"
"101010101100000000100110101010"
"010101001100000000101101010101"
"000000100000000000010000000010"
"101010110000000000010010101010"
"010101011000000000000101010110"
"000000001000000000001000000010"
"101010001000000000001010101000"
"010101010000000000001101010101"
"000000001100000000000000000010"
"101010110010000000010110101010"
"010101010100000001111001010100"
"000000001110110111111100000011"
"101010100110111101011010101010"
"010101010101010101010011101000"
"000000000000000000001101100000"
"101010101010101010100000100110"
"101001001101110001001011010000"
"100100110110001010011000011100"
"011011000001011011100100100110"
"111001100000101101000111001000"
"111100000110000011011101001110"
"010100101001110111101010110010"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
#ifdef TEST_RSS_GENERATE_EXPECTED
printf("symbology %d, data %s, length %d, rows %d, width %d\n", symbol->symbology, data[i].data, length, symbol->rows, symbol->width);
testUtilModulesDump(symbol);
#else
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);
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_best_supported_set();
testReport();
return 0;
}

175
backend/tests/test_rss.c Normal file
View File

@ -0,0 +1,175 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
//#define TEST_RSS_LINEAR_GENERATE_EXPECTED 1
//#define TEST_RSS_COMPOSITE_GENERATE_EXPECTED 1
static void test_linear(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_render;
int expected_rows;
int expected_width;
unsigned char* expected;
};
struct item data[] = {
/* 0*/ { BARCODE_RSS14, "1234567890123", 0, 100, 30, 1, 1, 96, "010111010010000001001110000000010100001011111010110100011001100101111111110001011011000111000101" },
/* 1*/ { BARCODE_RSS14, "0000004537076", 0, 100, 30, 1, 1, 96, "010101001000000001000100000000010111111100101010111101111101010101111111110111010100100000000101" },
/* 2*/ { BARCODE_RSS14, "0000004537077", 0, 100, 30, 1, 1, 96, "010101001000000001000111000000010111111101001010101010110000000101111100000111011111111011010101" },
/* 3*/ { BARCODE_RSS14, "0000004537078", 0, 100, 30, 1, 1, 96, "010101001000000001000111000000010111111101001010101011010000000101111000000011011111111011010101" },
/* 4*/ { BARCODE_RSS14, "0000000001596", 0, 100, 30, 1, 1, 96, "010101001000000001001111100000010111111100101010111101111101010101111100000111011111111011010101" },
/* 5*/ { BARCODE_RSS14, "0000000001597", 0, 100, 30, 1, 1, 96, "010101001000000001011111000000010111111100101010101010110000000101111100000111011111110111010101" },
/* 6*/ { BARCODE_RSS14, "0000000001598", 0, 100, 30, 1, 1, 96, "010101001000000001011111000000010111111100101010101011010000000101111000000011011111110111010101" },
/* 7*/ { BARCODE_RSS_LTD, "1234567890123", 0, 100, 30, 1, 1, 74, "01001100111100101000100111010110101011001001010010101001010000011100011101" },
/* 8*/ { BARCODE_RSS_LTD, "0000002013570", 0, 100, 30, 1, 1, 74, "01010101010100000010000001110100101101011001010111111110111111010101010101" },
/* 9*/ { BARCODE_RSS_LTD, "0000002013571", 0, 100, 30, 1, 1, 74, "01010101010100000011000000110101011010100011010101010101000000100000011101" },
/*10*/ { BARCODE_RSS_LTD, "0000002013572", 0, 100, 30, 1, 1, 74, "01010101010100000011000000110101010010111001010101010101000000110000001101" },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
#ifdef TEST_RSS_LINEAR_GENERATE_EXPECTED
printf("symbology %d, data %s, length %d, rows %d, height %d\n", symbol->symbology, data[i].data, length, symbol->rows, symbol->height);
testUtilModulesDump(symbol);
#else
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);
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_composite(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
unsigned char* composite;
int ret_encode;
float w;
float h;
int ret_render;
int expected_rows;
int expected_width;
unsigned char* expected;
};
struct item data[] = {
/* 0*/ { BARCODE_RSS14_CC, "0361234567890", "[11]990102", 0, 100, 30, 1, 5, 100, // TODO: verify expected
"1101101110111010001001110001100110010100000010011101001110100110011110011101110010010000110110001010"
"1101101100111000010011010001000010111110011010011001001011111001000111011111010001101110110010001010"
"1101101000110111110010010001011110100100000010011001101001111000110011011000010111111010111010001010"
"0000000000010110001110100000000101001011010111111011001101010000011010000000010100101000110011110000"
"0000010011101001110001001111111000010100101000000100110010101111100101111111100011010111001100001101"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length);
strcpy(symbol->primary, data[i].data);
int composite_length = strlen(data[i].composite);
ret = ZBarcode_Encode(symbol, data[i].composite, composite_length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
#ifdef TEST_RSS_COMPOSITE_GENERATE_EXPECTED
printf("symbology %d, data %s, length %d, rows %d, height %d\n", symbol->symbology, data[i].data, length, symbol->rows, symbol->height);
testUtilModulesDump(symbol);
#else
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);
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_linear();
test_composite();
testReport();
return 0;
}

209
backend/tests/test_upcean.c Normal file
View File

@ -0,0 +1,209 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include "testcommon.h"
static void test_upce_length(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
int ret;
};
struct item data[] = {
/* 0*/ { BARCODE_UPCE, "12345", 0 },
/* 1*/ { BARCODE_UPCE_CHK, "12345", ZINT_ERROR_INVALID_CHECK },
/* 2*/ { BARCODE_UPCE_CHK, "12344", 0 }, // 4 is correct check digit
/* 3*/ { BARCODE_UPCE, "123456", 0 },
/* 4*/ { BARCODE_UPCE_CHK, "123456", ZINT_ERROR_INVALID_CHECK },
/* 5*/ { BARCODE_UPCE_CHK, "123457", 0 }, // 7 is correct check digit
/* 6*/ { BARCODE_UPCE, "1234567", 0 },
/* 7*/ { BARCODE_UPCE_CHK, "1234567", ZINT_ERROR_INVALID_CHECK },
/* 8*/ { BARCODE_UPCE_CHK, "1234565", 0 }, // 5 is correct check digit
/* 9*/ { BARCODE_UPCE, "12345678", ZINT_ERROR_TOO_LONG },
/*10*/ { BARCODE_UPCE_CHK, "12345678", ZINT_ERROR_INVALID_CHECK },
/*11*/ { BARCODE_UPCE_CHK, "12345670", 0 }, // 0 is correct check digit
/*12*/ { BARCODE_UPCE, "123456789", ZINT_ERROR_TOO_LONG },
/*13*/ { BARCODE_UPCE_CHK, "123456789", ZINT_ERROR_TOO_LONG },
/*14*/ { BARCODE_UPCE, "123406", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 6, 2nd last can't be zero
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_isbn(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_render;
};
struct item data[] = {
/* 0*/ { "0", 0, 100, 30, 1 }, // Left zero-padded if < 10 chars
/* 1*/ { "12345678", ZINT_ERROR_INVALID_CHECK, 100, 30, -1 },
/* 2*/ { "12345679", 0, 100, 30, 1 }, // 9 is correct check digit
/* 3*/ { "123456789", 0, 100, 30, 1 },
/* 4*/ { "0123456789", 0, 100, 30, 1 },
/* 5*/ { "1234567890", ZINT_ERROR_INVALID_CHECK, 100, 30, -1 },
/* 6*/ { "123456789X", 0, 100, 30, 1 }, // X is correct check digit
/* 7*/ { "8175257660", 0, 100, 30, 1 }, // 0 is correct check digit
/* 8*/ { "0590764845", 0, 100, 30, 1 }, // 5 is correct check digit
/* 9*/ { "0906495741", 0, 100, 30, 1 }, // 1 is correct check digit
/*10*/ { "0140430016", 0, 100, 30, 1 }, // 6 is correct check digit
/*11*/ { "0571086187", 0, 100, 30, 1 }, // 7 is correct check digit
/*12*/ { "0486600882", 0, 100, 30, 1 }, // 2 is correct check digit
/*13*/ { "12345678901", ZINT_ERROR_TOO_LONG, 100, 30, -1 },
/*14*/ { "123456789012", ZINT_ERROR_TOO_LONG, 100, 30, -1 },
/*15*/ { "1234567890123", ZINT_ERROR_INVALID_DATA, 100, 30, -1 },
/*16*/ { "9784567890120", 0, 100, 30, 1 }, // 0 is correct check digit
/*17*/ { "9783161484100", 0, 100, 30, 1 }, // 0 is correct check digit
/*18*/ { "9781846688225", 0, 100, 30, 1 }, // 5 is correct check digit
/*19*/ { "9781847657954", 0, 100, 30, 1 }, // 4 is correct check digit
/*20*/ { "9781846688188", 0, 100, 30, 1 }, // 8 is correct check digit
/*21*/ { "9781847659293", 0, 100, 30, 1 }, // 3 is correct check digit
/*22*/ { "97845678901201", ZINT_ERROR_TOO_LONG, 100, 30, -1 },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_ISBNX;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d, errtxt %s\n", i, ret, data[i].ret_encode, symbol->errtxt);
if (data[i].ret_render != -1) {
ret = ZBarcode_Render( symbol, data[i].w, data[i].h );
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_render_same(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_render;
};
struct item data[] = {
/* 0*/ { BARCODE_UPCE, "123456", 0, 100, 30, 1 },
/* 1*/ { BARCODE_UPCE_CHK, "1234565", 0, 100, 30, 1 }, // 5 is correct check digit
/* 1*/ { BARCODE_ISBNX, "0195049969", 0, 100, 30, 1 }, // 9 is correct check digit
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_render* renders[4];
int renders_size = sizeof(renders) / sizeof(struct zint_render*);
for (int j = 0; j < renders_size; j++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
ret = ZBarcode_Render(symbol, data[i].w, data[i].h);
assert_equal(ret, data[i].ret_render, "i:%d ZBarcode_Render ret %d != %d\n", i, ret, data[i].ret_render);
assert_nonnull(symbol->rendered, "i:%d symbol->rendered NULL\n", i);
renders[j] = testUtilRenderCpy(symbol->rendered);
ZBarcode_Delete(symbol);
}
for (int j = 1; j < renders_size; j++) {
ret = testUtilRenderCmp(renders[j - 1], renders[j]);
assert_zero(ret, "i:%d testUtilRenderCmp ret %d != 0\n", i, ret);
}
for (int j = 0; j < renders_size; j++) {
struct zint_symbol symbol_render;
symbol_render.rendered = renders[j];
render_free(&symbol_render);
}
}
testFinish();
}
int main()
{
test_upce_length();
test_isbn();
test_render_same();
testReport();
return 0;
}

419
backend/tests/testcommon.c Normal file
View File

@ -0,0 +1,419 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
* Adapted from qrencode/tests/common.c
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*/
#include <stdio.h>
#include <string.h>
#include "testcommon.h"
extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
static int tests = 0;
static int failed = 0;
int assertionFailed = 0;
int assertionNum = 0;
static const char *testName = NULL;
static const char *testFunc = NULL;
void testStartReal(const char *func, const char *name)
{
tests++;
testName = name;
testFunc = func;
assertionFailed = 0;
assertionNum = 0;
printf("_____%d: %s: %s...\n", tests, func, name);
}
void testEnd(int result)
{
if (testName[0]) {
printf(".....%d: %s: %s ", tests, testFunc, testName);
} else {
printf(".....%d: %s: ", tests, testFunc);
}
if (result) {
puts("FAILED.");
failed++;
} else {
puts("PASSED.");
}
}
void testFinish(void)
{
if (testName[0]) {
printf(".....%d: %s: %s ", tests, testFunc, testName);
} else {
printf(".....%d: %s: ", tests, testFunc);
}
if (assertionFailed) {
printf("FAILED. (%d assertions failed.)\n", assertionFailed);
failed++;
} else {
printf("PASSED. (%d assertions passed.)\n", assertionNum);
}
}
void testReport()
{
if ( failed ) {
printf("Total %d tests, %d fails.\n", tests, failed);
exit(-1);
} else {
printf("Total %d tests, all passed.\n", tests);
}
}
int testUtilDAFTConvert(const struct zint_symbol* symbol, char* buffer, int buffer_size)
{
buffer[0] = '\0';
char* b = buffer;
for (int i = 0; i < symbol->width && b < buffer + buffer_size; i += 2) {
if (module_is_set(symbol, 0, i) && module_is_set(symbol, 2, i)) {
*b++ = 'F';
} else if (module_is_set(symbol, 0, i)) {
*b++ = 'A';
} else if (module_is_set(symbol, 2, i)) {
*b++ = 'D';
} else {
*b++ = 'T';
}
}
if (b == buffer + buffer_size) {
return FALSE;
}
*b = '\0';
return TRUE;
}
char* testUtilReadCSVField(char* buffer, char* field, int field_size)
{
int i;
char* b = buffer;
for (i = 0; i < field_size && *b && *b != ',' && *b != '\n' && *b != '\r'; i++) {
field[i] = *b++;
}
if (i == field_size) {
return NULL;
}
field[i] = '\0';
return b;
}
int testUtilSymbolCmp(const struct zint_symbol* a, const struct zint_symbol* b)
{
if (a->symbology != b->symbology) {
return 1;
}
if (a->rows != b->rows) {
return 2;
}
if (a->width != b->width) {
return 3;
}
for (int i = 0; i < a->rows; i++) {
for (int j = 0; j < a->width; j++) {
if (module_is_set(a, i, j) != module_is_set(b, i, j)) {
return 4;
}
}
}
if (a->height != b->height) {
return 5;
}
if (a->whitespace_width != b->whitespace_width) {
return 6;
}
if (a->border_width != b->border_width) {
return 7;
}
if (a->output_options != b->output_options) {
return 8;
}
if (a->scale != b->scale) {
return 9;
}
return 0;
}
struct zint_render* testUtilRenderCpy(const struct zint_render* in)
{
struct zint_render* out = (struct zint_render*)malloc(sizeof(struct zint_render));
out->width = in->width;
out->height = in->height;
out->lines = NULL;
out->strings = NULL;
out->rings = NULL;
out->hexagons = NULL;
struct zint_render_line* line;
struct zint_render_string* string;
struct zint_render_ring* ring;
struct zint_render_hexagon* hexagon;
struct zint_render_line** outline;
struct zint_render_string** outstring;
struct zint_render_ring** outring;
struct zint_render_hexagon** outhexagon;
// Copy lines
line = in->lines;
outline = &(out->lines);
while (line) {
*outline = (struct zint_render_line*) malloc(sizeof(struct zint_render_line));
memcpy(*outline, line, sizeof(struct zint_render_line));
outline = &((*outline)->next);
line = line->next;
}
*outline = NULL;
// Copy Strings
string = in->strings;
outstring = &(out->strings);
while (string) {
*outstring = (struct zint_render_string*) malloc(sizeof(struct zint_render_string));
memcpy(*outstring, string, sizeof(struct zint_render_string));
(*outstring)->text = (unsigned char*) malloc(sizeof(unsigned char) * (strlen(string->text) + 1));
strcpy((*outstring)->text, string->text);
outstring = &((*outstring)->next);
string = string->next;
}
*outstring = NULL;
// Copy Rings
ring = in->rings;
outring = &(out->rings);
while (ring) {
*outring = (struct zint_render_ring*) malloc(sizeof(struct zint_render_ring));
memcpy(*outring, ring, sizeof(struct zint_render_ring));
outring = &((*outring)->next);
ring = ring->next;
}
*outstring = NULL;
// Copy Hexagons
hexagon = in->hexagons;
outhexagon = &(out->hexagons);
while (hexagon) {
*outhexagon = (struct zint_render_hexagon*) malloc(sizeof(struct zint_render_hexagon));
memcpy(*outhexagon, hexagon, sizeof(struct zint_render_hexagon));
outhexagon = &((*outhexagon)->next);
hexagon = hexagon->next;
}
*outhexagon = NULL;
return out;
}
int testUtilRenderCmp(const struct zint_render* a, const struct zint_render* b)
{
struct zint_render_line* aline;
struct zint_render_string* astring;
struct zint_render_ring* aring;
struct zint_render_hexagon* ahexagon;
struct zint_render_line* bline;
struct zint_render_string* bstring;
struct zint_render_ring* bring;
struct zint_render_hexagon* bhexagon;
if (a->width != b->width) {
return 1;
}
if (a->height != b->height) {
return 2;
}
// Compare lines
aline = a->lines;
bline = b->lines;
while (aline) {
if (!bline) {
return 11;
}
if (aline->x != bline->x) {
return 12;
}
if (aline->y != bline->y) {
return 13;
}
if (aline->length != bline->length) {
return 14;
}
if (aline->width != bline->width) {
return 15;
}
aline = aline->next;
bline = bline->next;
}
if (bline) {
return 10;
}
// Compare strings
astring = a->strings;
bstring = b->strings;
while (astring) {
if (!bstring) {
return 21;
}
if (astring->x != bstring->x) {
return 22;
}
if (astring->y != bstring->y) {
return 23;
}
if (astring->fsize != bstring->fsize) {
return 24;
}
if (astring->width != bstring->width) {
return 25;
}
if (astring->length != bstring->length) {
return 26;
}
if (strlen(astring->text) != strlen(bstring->text)) {
return 27;
}
if (strcmp(astring->text, bstring->text) != 0) {
return 28;
}
astring = astring->next;
bstring = bstring->next;
}
if (bstring) {
return 20;
}
// Compare rings
aring = a->rings;
bring = b->rings;
while (aring) {
if (!bring) {
return 31;
}
if (aring->x != bring->x) {
return 32;
}
if (aring->y != bring->y) {
return 33;
}
if (aring->radius != bring->radius) {
return 34;
}
if (aring->line_width != bring->line_width) {
return 35;
}
aring = aring->next;
bring = bring->next;
}
if (bring) {
return 30;
}
// Compare hexagons
ahexagon = a->hexagons;
bhexagon = b->hexagons;
while (ahexagon) {
if (!bhexagon) {
return 41;
}
if (ahexagon->x != bhexagon->x) {
return 42;
}
if (ahexagon->y != bhexagon->y) {
return 43;
}
if (ahexagon->height != bhexagon->height) {
return 44;
}
ahexagon = ahexagon->next;
bhexagon = bhexagon->next;
}
if (bhexagon) {
return 40;
}
return 0;
}
void testUtilLargeDump(const char* name, const short int reg[])
{
unsigned words[4];
words[0] = words[1] = words[2] = words[3] = 0;
int w = 0;
for (int i = 0; i < 112; i += 32 ) {
for (int j = 0; j < 32 && i + j < 112; j++) {
if (reg[i + j]) {
words[w] += 1 << j;
}
}
w++;
}
printf("%4x 0x%08x%08x%08x %s", words[3], words[2], words[1], words[0], name);
}
void testUtilModulesDump(const struct zint_symbol* symbol)
{
int r, w;
for (r = 0; r < symbol->rows; r++) {
putchar('"');
for (w = 0; w < symbol->width; w++) {
putchar(module_is_set(symbol, r, w) ? '1' : '0');
}
puts("\"");
}
putchar('\n');
}
int testUtilModulesCmp(const struct zint_symbol* symbol, const char* expected, int* row, int* width)
{
const char* e = expected;
const char* ep = expected + strlen(expected);
int r, w;
for (r = 0; r < symbol->rows && e < ep; r++) {
for (w = 0; w < symbol->width && e < ep; w++) {
if (module_is_set(symbol, r, w) != (*e == '1')) {
*row = r;
*width = w;
return 1 /*fail*/;
}
e++;
}
}
*row = r;
*width = w;
return e != ep || r != symbol->rows || w != symbol->width ? 1 /*fail*/ : 0 /*success*/;
}

View File

@ -0,0 +1,76 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
* Adapted from qrencode/tests/common.h
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*/
#ifndef TESTCOMMON_H
#define TESTCOMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zint.h>
#include "../common.h"
extern int assertionFailed;
extern int assertionNum;
#define testStart(__arg__) (testStartReal(__func__, __arg__))
#define testEndExp(__arg__) (testEnd(!(__arg__)))
void testStartReal(const char *func, const char *name);
void testEnd(int result);
void testFinish(void);
void testReport();
#define assert_exp(__exp__, ...) \
{assertionNum++;if(!(__exp__)) {assertionFailed++; printf(__VA_ARGS__);testFinish();return;}}
#define assert_zero(__exp__, ...) assert_exp((__exp__) == 0, __VA_ARGS__)
#define assert_nonzero(__exp__, ...) assert_exp((__exp__) != 0, __VA_ARGS__)
#define assert_null(__ptr__, ...) assert_exp((__ptr__) == NULL, __VA_ARGS__)
#define assert_nonnull(__ptr__, ...) assert_exp((__ptr__) != NULL, __VA_ARGS__)
#define assert_equal(__e1__, __e2__, ...) assert_exp((__e1__) == (__e2__), __VA_ARGS__)
#define assert_notequal(__e1__, __e2__, ...) assert_exp((__e1__) != (__e2__), __VA_ARGS__)
#define assert_nothing(__exp__, ...) {printf(__VA_ARGS__); __exp__;}
extern void render_free(struct zint_symbol *symbol); /* Free render structures */
int testUtilDAFTConvert(const struct zint_symbol* symbol, char* buffer, int buffer_size);
char* testUtilReadCSVField(char* buffer, char* field, int field_size);
int testUtilSymbolCmp(const struct zint_symbol* a, const struct zint_symbol* b);
struct zint_render* testUtilRenderCpy(const struct zint_render* in);
int testUtilRenderCmp(const struct zint_render* a, const struct zint_render* b);
void testUtilLargeDump(const char* name, const short reg[]);
void testUtilModulesDump(const struct zint_symbol* symbol);
int testUtilModulesCmp(const struct zint_symbol* symbol, const char* expected, int* row, int* width);
#endif /* TESTCOMMON_H */

776
frontend/main.c Normal file
View File

@ -0,0 +1,776 @@
/* main.c - Command line handling routines for Zint */
/*
libzint - the open source barcode library
Copyright (C) 2008-2016 Robin Stuart <rstuart114@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _MSC_VER
#include <getopt.h>
#include <zint.h>
#else
#include "getopt.h"
#include "zint.h"
#endif
#define NESET "0123456789"
#ifdef _MSC_VER
#include <malloc.h>
#endif
/* Print list of supported symbologies */
void types(void) {
printf( " 1: Code 11 51: Pharma One-Track 92: Aztec Code\n"
" 2: Standard 2of5 52: PZN 93: DAFT Code\n"
" 3: Interleaved 2of5 53: Pharma Two-Track 97: Micro QR Code\n"
" 4: IATA 2of5 55: PDF417 98: HIBC Code 128\n"
" 6: Data Logic 56: PDF417 Trunc 99: HIBC Code 39\n"
" 7: Industrial 2of5 57: Maxicode 102: HIBC Data Matrix\n"
" 8: Code 39 58: QR Code 104: HIBC QR Code\n"
" 9: Extended Code 39 60: Code 128-B 106: HIBC PDF417\n"
"13: EAN 63: AP Standard Customer 108: HIBC MicroPDF417\n"
"14: EAN + Check 66: AP Reply Paid 110: HIBC Codablock-F\n"
"16: GS1-128 67: AP Routing 112: HIBC Aztec Code\n"
"18: Codabar 68: AP Redirection 115: DotCode\n"
"20: Code 128 69: ISBN 116: Han Xin Code\n"
"21: Leitcode 70: RM4SCC 121: RM Mailmark\n"
"22: Identcode 71: Data Matrix 128: Aztec Runes\n"
"23: Code 16k 72: EAN-14 129: Code 32\n"
"24: Code 49 73: VIN (North America) 130: Comp EAN\n"
"25: Code 93 74: Codablock-F 131: Comp GS1-128\n"
"28: Flattermarken 75: NVE-18 132: Comp DataBar Omni\n"
"29: GS1 DataBar Omni 76: Japanese Post 133: Comp DataBar Ltd\n"
"30: GS1 DataBar Ltd 77: Korea Post 134: Comp DataBar ExpOm\n"
"31: GS1 DataBar ExpOm 79: GS1 DataBar Stack 135: Comp UPC-A\n"
"32: Telepen Alpha 80: GS1 DataBar Stack Omni 136: Comp UPC-E\n"
"34: UPC-A 81: GS1 DataBar ESO 137: Comp DataBar Stack\n"
"35: UPC-A + Check 82: Planet 138: Comp DataBar Stack Omni\n"
"37: UPC-E 84: MicroPDF 139: Comp DataBar ESO\n"
"38: UPC-E + Check 85: USPS OneCode 140: Channel Code\n"
"40: Postnet 86: UK Plessey 141: Code One\n"
"47: MSI Plessey 87: Telepen Numeric 142: Grid Matrix\n"
"49: FIM 89: ITF-14 143: UPNQR\n"
"50: Logmars 90: KIX Code\n"
);
}
/* Output usage information */
void usage(void) {
printf( "Zint version %d.%d.%d\n"
"Encode input data in a barcode and save as BMP/EMF/EPS/GIF/PCX/PNG/SVG/TIF\n\n"
" -b, --barcode=NUMBER Number of barcode type (default is 20 (=Code128)).\n"
" --batch Treat each line of input file as a separate data set\n"
" --bg=COLOUR Specify a background colour (in hex)\n"
" --binary Treat input as raw binary data\n"
" --bind Add boundary bars\n"
" --bold Use bold text\n"
" --border=NUMBER Set width of border in multiples of x-dimension\n"
" --box Add a box around the symbol\n"
" --cmyk Use CMYK colour space in EPS symbols\n"
" --cols=NUMBER Set the number of data columns in symbol\n"
" -d, --data=DATA Set the symbol content\n"
" --direct Send output to stdout\n"
" --dotsize=NUMBER Set radius of dots in dotty mode\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"
" -e, --ecinos Display table of ECI character encodings\n"
" --eci=NUMBER Set the ECI mode for raw 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"
" --gs1 Treat input as GS1 compatible data\n"
" -h, --help Display help message\n"
" --height=NUMBER Set height of symbol in multiples of x-dimension\n"
" -i, --input=FILE Read input data from FILE\n"
" --init Create reader initialisation/programming symbol\n"
" --mirror Use batch data to determine filename\n"
" --mode=NUMBER Set encoding mode (Maxicode/Composite)\n"
" --notext Remove human readable text\n"
" -o, --output=FILE Send output to FILE. (default is out.png)\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"
" --small Use half-size text in PNG images\n"
" --square Force Data Matrix symbols to be square\n"
" -r, --reverse Reverse colours (white on black)\n"
" --rotate=NUMBER Rotate symbol by NUMBER degrees (PNG/BMP/PCX)\n"
" --rows=NUMBER Set number of rows (Codablock-F)\n"
" -t, --types Display table of barcode types\n"
" --vers=NUMBER Set symbol version (QR Code/Han Xin)\n"
" -w, --whitesp=NUMBER Set Width of whitespace in multiples of x-dimension\n"
, ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
}
/* Display supported ECI codes */
void show_eci(void) {
printf( " 3: ISO-8859-1 - Latin alphabet No. 1 (default)\n"
" 4: ISO-8859-2 - Latin alphabet No. 2\n"
" 5: ISO-8859-3 - Latin alphabet No. 3\n"
" 6: ISO-8859-4 - Latin alphabet No. 4\n"
" 7: ISO-8859-5 - Latin/Cyrillic alphabet\n"
" 8: ISO-8859-6 - Latin/Arabic alphabet\n"
" 9: ISO-8859-7 - Latin/Greek alphabet\n"
"10: ISO-8859-8 - Latin/Hebrew alphabet\n"
"11: ISO-8859-9 - Latin alphabet No. 5\n"
"12: ISO-8859-10 - Latin alphabet No. 6\n"
"13: ISO-8859-11 - Latin/Thai alphabet\n"
"15: ISO-8859-13 - Latin alphabet No. 7\n"
"16: ISO-8859-14 - Latin alphabet No. 8 (Celtic)\n"
"17: ISO-8859-15 - Latin alphabet No. 9\n"
"18: ISO-8859-16 - Latin alphabet No. 10\n"
"20: ** Shift-JIS (JISX 0208 amd JISX 0201)\n"
"21: Windows-1250\n"
"22: Windows-1251\n"
"23: Windows-1252\n"
"24: Windows-1256\n"
"25: ** UCS-2 Unicode (High order byte first)\n"
"26: Unicode (UTF-8)\n"
"27: ISO-646:1991 7-bit character set\n"
"28: ** Big-5 (Taiwan) Chinese Character Set\n"
"29: ** GB (PRC) Chinese Character Set\n"
"30: ** Korean Character Set (KSX1001:1998)\n"
"** See note in section 4.10 of the manual\n"
);
}
/* Verifies that a string only uses valid characters */
int validator(char test_string[], char source[]) {
unsigned int i, j;
for (i = 0; i < strlen(source); i++) {
unsigned int latch = 0;
for (j = 0; j < strlen(test_string); j++) {
if (source[i] == test_string[j]) {
latch = 1;
}
}
if (!(latch)) {
return ZINT_ERROR_INVALID_DATA;
}
}
return 0;
}
/* Converts an integer value to its hexadecimal character */
static char itoc(int source) {
if ((source >= 0) && (source <= 9)) {
return ('0' + source);
} else {
return ('A' + (source - 10));
}
}
/* Concatinates dest[] with the contents of source[], copying /0 as well */
static void concat(char dest[], char source[]) {
unsigned int i, j, n;
j = strlen(dest);
n = strlen(source);
for (i = 0; i <= n; i++) {
dest[i + j] = source[i];
}
}
int batch_process(struct zint_symbol *symbol, char *filename, int mirror_mode, char *filetype, int rotate_angle) {
FILE *file;
unsigned char buffer[7100];
unsigned char character = 0;
int posn = 0, error_number = 0, line_count = 1;
char output_file[256];
char number[12], reverse_number[12];
int inpos, local_line_count;
char format_string[127], reversed_string[127], format_char;
int format_len, i;
char adjusted[2];
memset(buffer, 0, sizeof (unsigned char) * 7100);
memset(format_string, 0, sizeof (unsigned char) * 127);
if (symbol->outfile[0] == '\0') {
strcpy(format_string, "~~~~~.");
strcat(format_string, filetype);
} else {
if (strlen(format_string) < 127) {
strcpy(format_string, symbol->outfile);
} else {
strcpy(symbol->errtxt, "101: Format string too long");
return ZINT_ERROR_INVALID_DATA;
}
}
memset(adjusted, 0, sizeof (char) * 2);
if (!strcmp(filename, "-")) {
file = stdin;
} else {
file = fopen(filename, "rb");
if (!file) {
strcpy(symbol->errtxt, "102: Unable to read input file");
return ZINT_ERROR_INVALID_DATA;
}
}
do {
int intChar;
intChar = fgetc(file);
if (intChar == EOF) {
break;
}
character = (unsigned char) intChar;
if (character == '\n') {
if (buffer[posn - 1] == '\r') {
/* CR+LF - assume Windows formatting and remove CR */
posn--;
buffer[posn] = '\0';
}
if (mirror_mode == 0) {
inpos = 0;
local_line_count = line_count;
memset(number, 0, sizeof (char) * 12);
memset(reverse_number, 0, sizeof (char) * 12);
memset(reversed_string, 0, sizeof (char) * 127);
memset(output_file, 0, sizeof (char) * 127);
do {
number[inpos] = itoc(local_line_count % 10);
local_line_count /= 10;
inpos++;
} while (local_line_count > 0);
number[inpos] = '\0';
for (i = 0; i < inpos; i++) {
reverse_number[i] = number[inpos - i - 1];
}
format_len = strlen(format_string);
for (i = format_len; i > 0; i--) {
format_char = format_string[i - 1];
switch (format_char) {
case '#':
if (inpos > 0) {
adjusted[0] = reverse_number[inpos - 1];
inpos--;
} else {
adjusted[0] = ' ';
}
break;
case '~':
if (inpos > 0) {
adjusted[0] = reverse_number[inpos - 1];
inpos--;
} else {
adjusted[0] = '0';
}
break;
case '@':
if (inpos > 0) {
adjusted[0] = reverse_number[inpos - 1];
inpos--;
} else {
adjusted[0] = '*';
}
break;
default:
adjusted[0] = format_string[i - 1];
break;
}
concat(reversed_string, adjusted);
}
for (i = 0; i < format_len; i++) {
output_file[i] = reversed_string[format_len - i - 1];
}
} else {
/* Name the output file from the data being processed */
for (i = 0; (i < posn && i < 250); i++) {
if (buffer[i] < 0x20) {
output_file[i] = '_';
} else {
switch (buffer[i]) {
case 0x21: // !
case 0x22: // "
case 0x2a: // *
case 0x2f: // /
case 0x3a: // :
case 0x3c: // <
case 0x3e: // >
case 0x3f: // ?
case 0x7c: // |
case 0x7f: // DEL
output_file[i] = '_';
break;
default:
output_file[i] = buffer[i];
}
}
}
/* Add file extension */
output_file[i] = '.';
output_file[i + 1] = '\0';
strcat(output_file, filetype);
}
strcpy(symbol->outfile, output_file);
error_number = ZBarcode_Encode_and_Print(symbol, buffer, posn, rotate_angle);
if (error_number != 0) {
fprintf(stderr, "On line %d: %s\n", line_count, symbol->errtxt);
fflush(stderr);
}
ZBarcode_Clear(symbol);
memset(buffer, 0, sizeof (unsigned char) * 7100);
posn = 0;
line_count++;
} else {
buffer[posn] = character;
posn++;
}
if (posn > 7090) {
fprintf(stderr, "On line %d: Error 103: Input data too long\n", line_count);
fflush(stderr);
do {
character = fgetc(file);
} while ((!feof(file)) && (character != '\n'));
}
} while ((!feof(file)) && (line_count < 2000000000));
if (character != '\n') {
fprintf(stderr, "Warning 104: No newline at end of file\n");
fflush(stderr);
}
fclose(file);
return error_number;
}
int main(int argc, char **argv) {
struct zint_symbol *my_symbol;
int error_number;
int rotate_angle;
int generated;
int batch_mode;
int mirror_mode;
char filetype[4];
int i;
error_number = 0;
rotate_angle = 0;
generated = 0;
my_symbol = ZBarcode_Create();
my_symbol->input_mode = UNICODE_MODE;
batch_mode = 0;
mirror_mode = 0;
for (i = 0; i < 4; i++) {
filetype[i] = '\0';
}
if (argc == 1) {
usage();
exit(1);
}
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"types", 0, 0, 't'},
{"ecinos", 0, 0, 'e'},
{"bind", 0, 0, 0},
{"box", 0, 0, 0},
{"direct", 0, 0, 0},
{"dump", 0, 0, 0},
{"barcode", 1, 0, 'b'},
{"height", 1, 0, 0},
{"whitesp", 1, 0, 'w'},
{"border", 1, 0, 0},
{"data", 1, 0, 'd'},
{"output", 1, 0, 'o'},
{"input", 1, 0, 'i'},
{"fg", 1, 0, 0},
{"bg", 1, 0, 0},
{"cols", 1, 0, 0},
{"rows", 1, 0, 0},
{"vers", 1, 0, 0},
{"rotate", 1, 0, 0},
{"secure", 1, 0, 0},
{"reverse", 1, 0, 'r'},
{"mode", 1, 0, 0},
{"primary", 1, 0, 0},
{"scale", 1, 0, 0},
{"gs1", 0, 0, 0},
{"binary", 0, 0, 0},
{"notext", 0, 0, 0},
{"square", 0, 0, 0},
{"dmre", 0, 0, 0},
{"init", 0, 0, 0},
{"small", 0, 0, 0},
{"bold", 0, 0, 0},
{"cmyk", 0, 0, 0},
{"batch", 0, 0, 0},
{"mirror", 0, 0, 0},
{"dotty", 0, 0, 0},
{"dotsize", 1, 0, 0},
{"eci", 1, 0, 0},
{"filetype", 1, 0, 0},
{"esc", 0, 0, 0},
{"fontsize", 1, 0, 0},
{"verbose", 0, 0, 0}, // Currently undocumented, output some debug info
{0, 0, 0, 0}
};
int c = getopt_long(argc, argv, "htb:w:d:o:i:rcmpe", long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0:
if (!strcmp(long_options[option_index].name, "bind")) {
my_symbol->output_options += BARCODE_BIND;
}
if (!strcmp(long_options[option_index].name, "box")) {
my_symbol->output_options += BARCODE_BOX;
}
if (!strcmp(long_options[option_index].name, "init")) {
my_symbol->output_options += READER_INIT;
}
if (!strcmp(long_options[option_index].name, "small")) {
my_symbol->output_options += SMALL_TEXT;
}
if (!strcmp(long_options[option_index].name, "bold")) {
my_symbol->output_options += BOLD_TEXT;
}
if (!strcmp(long_options[option_index].name, "cmyk")) {
my_symbol->output_options += CMYK_COLOUR;
}
if (!strcmp(long_options[option_index].name, "dotty")) {
my_symbol->output_options += BARCODE_DOTTY_MODE;
}
if (!strcmp(long_options[option_index].name, "direct")) {
my_symbol->output_options += BARCODE_STDOUT;
}
if (!strcmp(long_options[option_index].name, "dump")) {
my_symbol->output_options += BARCODE_STDOUT;
strncpy(my_symbol->outfile, "dummy.txt", 10);
}
if (!strcmp(long_options[option_index].name, "gs1")) {
my_symbol->input_mode = GS1_MODE;
}
if (!strcmp(long_options[option_index].name, "binary")) {
my_symbol->input_mode = DATA_MODE;
}
if (!strcmp(long_options[option_index].name, "fg")) {
strncpy(my_symbol->fgcolour, optarg, 7);
}
if (!strcmp(long_options[option_index].name, "bg")) {
strncpy(my_symbol->bgcolour, optarg, 7);
}
if (!strcmp(long_options[option_index].name, "notext")) {
my_symbol->show_hrt = 0;
}
if (!strcmp(long_options[option_index].name, "square")) {
my_symbol->option_3 = DM_SQUARE;
}
/* Square overwrites DMRE */
if (!strcmp(long_options[option_index].name, "dmre")
&& my_symbol->option_3 != DM_SQUARE) {
my_symbol->option_3 = DM_DMRE;
}
if (!strcmp(long_options[option_index].name, "scale")) {
my_symbol->scale = (float) (atof(optarg));
if (my_symbol->scale < 0.01) {
/* Zero and negative values are not permitted */
fprintf(stderr, "Warning 105: Invalid scale value\n");
fflush(stderr);
my_symbol->scale = 1.0;
}
}
if (!strcmp(long_options[option_index].name, "dotsize")) {
my_symbol->dot_size = (float) (atof(optarg));
if (my_symbol->dot_size < 0.01) {
/* Zero and negative values are not permitted */
fprintf(stderr, "Warning 106: Invalid dot radius value\n");
fflush(stderr);
my_symbol->dot_size = 4.0F / 5.0F;
}
}
if (!strcmp(long_options[option_index].name, "border")) {
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 107: Invalid border width\n");
exit(1);
}
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
my_symbol->border_width = atoi(optarg);
} else {
fprintf(stderr, "Warning 108: Border width out of range\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "height")) {
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 109: Invalid symbol height\n");
exit(1);
}
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 1000)) {
my_symbol->height = atoi(optarg);
} else {
fprintf(stderr, "Warning 110: Symbol height out of range\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "cols")) {
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 66)) {
my_symbol->option_2 = atoi(optarg);
} else {
fprintf(stderr, "Warning 111: Number of columns out of range\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "rows")) {
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 44)) {
my_symbol->option_1 = atoi(optarg);
} else {
fprintf(stderr, "Warning 112: Number of rows out of range\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "vers")) {
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 84)) {
my_symbol->option_2 = atoi(optarg);
} else {
fprintf(stderr, "Warning 113: Invalid Version\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "secure")) {
if ((atoi(optarg) >= 1) && (atoi(optarg) <= 8)) {
my_symbol->option_1 = atoi(optarg);
} else {
fprintf(stderr, "Warning 114: ECC level out of range\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "primary")) {
if (strlen(optarg) <= 90) {
strcpy(my_symbol->primary, optarg);
} else {
fprintf(stderr, "Error 115: Primary data string too long");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "mode")) {
if ((optarg[0] >= '0') && (optarg[0] <= '6')) {
my_symbol->option_1 = optarg[0] - '0';
} else {
fprintf(stderr, "Warning 116: Invalid mode\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "rotate")) {
/* Only certain inputs allowed */
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 117: Invalid rotation parameter\n");
exit(1);
}
switch (atoi(optarg)) {
case 90: rotate_angle = 90;
break;
case 180: rotate_angle = 180;
break;
case 270: rotate_angle = 270;
break;
default: rotate_angle = 0;
break;
}
}
if (!strcmp(long_options[option_index].name, "batch")) {
/* Switch to batch processing mode */
batch_mode = 1;
}
if (!strcmp(long_options[option_index].name, "mirror")) {
/* Use filenames which reflect content */
mirror_mode = 1;
}
if (!strcmp(long_options[option_index].name, "filetype")) {
/* Select the type of output file */
strncpy(filetype, optarg, (size_t) 3);
}
if (!strcmp(long_options[option_index].name, "eci")) {
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 999999)) {
my_symbol->eci = atoi(optarg);
} else {
fprintf(stderr, "Warning 118: Invalid ECI code\n");
fflush(stderr);
}
}
if (!strcmp(long_options[option_index].name, "esc")) {
if (!(my_symbol->input_mode & ESCAPE_MODE)) {
my_symbol->input_mode += ESCAPE_MODE;
}
}
if (!strcmp(long_options[option_index].name, "verbose")) {
my_symbol->debug = 1;
}
if (!strcmp(long_options[option_index].name, "fontsize")) {
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 100)) {
my_symbol->fontsize = atoi(optarg);
} else {
fprintf(stderr, "Warning 125: Invalid font size\n");
fflush(stderr);
}
}
break;
case 'h':
usage();
break;
case 't':
types();
break;
case 'e':
show_eci();
break;
case 'b':
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 119: Invalid barcode type\n");
exit(1);
}
my_symbol->symbology = atoi(optarg);
break;
case 'w':
error_number = validator(NESET, optarg);
if (error_number == ZINT_ERROR_INVALID_DATA) {
fprintf(stderr, "Error 120: Invalid whitespace value\n");
exit(1);
}
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) {
my_symbol->whitespace_width = atoi(optarg);
} else {
fprintf(stderr, "Warning 121: Whitespace value out of range");
fflush(stderr);
}
break;
case 'd': /* we have some data! */
if (batch_mode == 0) {
if (filetype[0] != '\0') {
strcat(my_symbol->outfile, ".");
strcat(my_symbol->outfile, filetype);
}
error_number = ZBarcode_Encode(my_symbol, (unsigned char*) optarg, strlen(optarg));
generated = 1;
if (error_number != 0) {
fprintf(stderr, "%s\n", my_symbol->errtxt);
fflush(stderr);
}
if (error_number < 5) {
error_number = ZBarcode_Print(my_symbol, rotate_angle);
if (error_number != 0) {
fprintf(stderr, "%s\n", my_symbol->errtxt);
fflush(stderr);
ZBarcode_Delete(my_symbol);
return 1;
}
}
} else {
fprintf(stderr, "Warning 122: Can't define data in batch mode");
fflush(stderr);
}
break;
case 'i': /* Take data from file */
if (batch_mode == 0) {
error_number = ZBarcode_Encode_File(my_symbol, optarg);
generated = 1;
if (error_number != 0) {
fprintf(stderr, "%s\n", my_symbol->errtxt);
fflush(stderr);
}
if (error_number < 5) {
error_number = ZBarcode_Print(my_symbol, rotate_angle);
if (error_number != 0) {
fprintf(stderr, "%s\n", my_symbol->errtxt);
fflush(stderr);
ZBarcode_Delete(my_symbol);
return 1;
}
}
} else {
/* Take each line of text as a separate data set */
if (filetype[0] == '\0') {
strcpy(filetype, "png");
}
error_number = batch_process(my_symbol, optarg, mirror_mode, filetype, rotate_angle);
generated = 1;
if (error_number != 0) {
fprintf(stderr, "%s\n", my_symbol->errtxt);
fflush(stderr);
ZBarcode_Delete(my_symbol);
return 1;
}
}
break;
case 'o':
strncpy(my_symbol->outfile, optarg, 250);
break;
case 'r':
strcpy(my_symbol->fgcolour, "ffffff");
strcpy(my_symbol->bgcolour, "000000");
break;
case '?':
break;
default:
fprintf(stderr, "Error 123: ?? getopt error 0%o\n", c);
fflush(stderr);
}
}
if (optind < argc) {
fprintf(stderr, "Error 125: Invalid option\n");
while (optind < argc)
fprintf(stderr, "%s", argv[optind++]);
fprintf(stderr, "\n");
fflush(stderr);
}
if (generated == 0) {
fprintf(stderr, "Warning 124: No data received, no symbol generated\n");
fflush(stderr);
}
ZBarcode_Delete(my_symbol);
return error_number;
}