From 511fadef30c0f8634c6a7126edae0554914bcb92 Mon Sep 17 00:00:00 2001 From: Robin Stuart Date: Thu, 10 Jun 2010 21:52:50 +0100 Subject: [PATCH] Initial transfer from CVS Transfer of version 2.3.2 from CVS repository --- CMakeLists.txt | 97 + COPYING | 674 +++ Makefile | 18 + SetPaths.cmake | 255 + backend/2of5.c | 363 ++ backend/CMakeLists.txt | 27 + backend/DEVELOPER | 133 + backend/Makefile | 54 + backend/Makefile.mingw | 79 + backend/auspost.c | 248 + backend/aztec.c | 1350 +++++ backend/aztec.h | 291 ++ backend/code.c | 542 ++ backend/code1.c | 1536 ++++++ backend/code1.h | 61 + backend/code128.c | 999 ++++ backend/code16k.c | 622 +++ backend/code49.c | 315 ++ backend/code49.h | 1175 +++++ backend/common.c | 397 ++ backend/common.h | 70 + backend/composite.c | 1954 +++++++ backend/composite.h | 62 + backend/dllversion.c | 31 + backend/dm200.c | 881 ++++ backend/dm200.h | 101 + backend/dmatrix.c | 1318 +++++ backend/dmatrix.h | 671 +++ backend/font.h | 57 + backend/gb2312.h | 7467 +++++++++++++++++++++++++++ backend/gridmtx.c | 1089 ++++ backend/gridmtx.h | 160 + backend/gs1.c | 287 + backend/gs1.h | 35 + backend/imail.c | 700 +++ backend/large.c | 227 + backend/large.h | 40 + backend/library.c | 837 +++ backend/libzint.rc | 42 + backend/maxicode.c | 702 +++ backend/maxicode.h | 90 + backend/maxipng.h | 138 + backend/medical.c | 308 ++ backend/ms_stdint.h | 234 + backend/pdf417.c | 1083 ++++ backend/pdf417.h | 438 ++ backend/plessey.c | 496 ++ backend/png.c | 1138 ++++ backend/postal.c | 603 +++ backend/ps.c | 778 +++ backend/qr.c | 2464 +++++++++ backend/qr.h | 156 + backend/reedsol.c | 161 + backend/reedsol.h | 40 + backend/rss.c | 2367 +++++++++ backend/rss.h | 225 + backend/sjis.h | 6875 ++++++++++++++++++++++++ backend/svg.c | 625 +++ backend/telepen.c | 157 + backend/upcean.c | 800 +++ backend/zint.h | 206 + backend_qt4/CMakeLists.txt | 22 + backend_qt4/QtZint2.sln | 20 + backend_qt4/QtZint2.vcproj | 411 ++ backend_qt4/backend_qt4.pro | 110 + backend_qt4/backend_vc8.pro | 74 + backend_qt4/qzint.cpp | 717 +++ backend_qt4/qzint.h | 121 + backend_qt4/readme | 9 + cmake/modules/FindQr.cmake | 29 + cmake/modules/FindZint.cmake | 58 + cmake_uninstall.cmake.in | 21 + debian/changelog | 44 + debian/compat | 1 + debian/control | 64 + debian/copyright | 39 + debian/libqzint-dev.install | 2 + debian/libqzint.install | 1 + debian/libzint-dev.install | 3 + debian/libzint.install | 1 + debian/qzintfrontend.install | 1 + debian/rules | 9 + debian/zintfrontend.install | 1 + docs/README | 3 + frontend/CMakeLists.txt | 19 + frontend/Makefile | 31 + frontend/Makefile.mingw | 37 + frontend/getopt.c | 1213 +++++ frontend/getopt.h | 169 + frontend/getopt1.c | 185 + frontend/main.c | 391 ++ frontend/test.sh | 423 ++ frontend/zint.rc | 85 + frontend/zint_black.ico | Bin 0 -> 25698 bytes frontend_qt4/CMakeLists.txt | 26 + frontend_qt4/barcodeitem.cpp | 42 + frontend_qt4/barcodeitem.h | 41 + frontend_qt4/datawindow.cpp | 103 + frontend_qt4/datawindow.h | 43 + frontend_qt4/exportwindow.cpp | 138 + frontend_qt4/exportwindow.h | 42 + frontend_qt4/extData.ui | 98 + frontend_qt4/extExport.ui | 178 + frontend_qt4/extSequence.ui | 272 + frontend_qt4/frontend_qt4.pro | 31 + frontend_qt4/frontend_vc8.pro | 40 + frontend_qt4/grpAztec.ui | 339 ++ frontend_qt4/grpC128.ui | 81 + frontend_qt4/grpC16k.ui | 55 + frontend_qt4/grpC39.ui | 62 + frontend_qt4/grpC49.ui | 55 + frontend_qt4/grpChannel.ui | 89 + frontend_qt4/grpCodablock.ui | 62 + frontend_qt4/grpCodeOne.ui | 127 + frontend_qt4/grpDBExtend.ui | 105 + frontend_qt4/grpDM.ui | 434 ++ frontend_qt4/grpGrid.ui | 199 + frontend_qt4/grpMQR.ui | 143 + frontend_qt4/grpMSICheck.ui | 79 + frontend_qt4/grpMaxicode.ui | 116 + frontend_qt4/grpMicroPDF.ui | 97 + frontend_qt4/grpPDF417.ui | 276 + frontend_qt4/grpQR.ui | 373 ++ frontend_qt4/images/.directory | 3 + frontend_qt4/images/rotateleft.png | Bin 0 -> 1754 bytes frontend_qt4/images/rotateright.png | Bin 0 -> 1732 bytes frontend_qt4/images/zint.png | Bin 0 -> 458 bytes frontend_qt4/images/zoomin.png | Bin 0 -> 1622 bytes frontend_qt4/images/zoomout.png | Bin 0 -> 1601 bytes frontend_qt4/main.cpp | 28 + frontend_qt4/mainWindow.ui | 793 +++ frontend_qt4/mainwindow.cpp | 874 ++++ frontend_qt4/mainwindow.h | 148 + frontend_qt4/qtZint.sln | 20 + frontend_qt4/qtZint.vcproj | 499 ++ frontend_qt4/res/.directory | 3 + frontend_qt4/res/qtZint.rc | 85 + frontend_qt4/res/zint.ico | Bin 0 -> 25842 bytes frontend_qt4/resources.qrc | 26 + frontend_qt4/sequencewindow.cpp | 196 + frontend_qt4/sequencewindow.h | 47 + gpl-3.0.txt | 674 +++ readme | 158 + readme-cmake | 6 + win32/libzint.vcproj | 517 ++ win32/test.bat | 837 +++ win32/zint.sln | 34 + win32/zint.vcproj | 285 + zint-qt.desktop | 8 + zint.nsi | 205 + zint.png | Bin 0 -> 458 bytes zint.spec | 144 + 152 files changed, 58999 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 Makefile create mode 100644 SetPaths.cmake create mode 100644 backend/2of5.c create mode 100644 backend/CMakeLists.txt create mode 100644 backend/DEVELOPER create mode 100644 backend/Makefile create mode 100644 backend/Makefile.mingw create mode 100644 backend/auspost.c create mode 100644 backend/aztec.c create mode 100644 backend/aztec.h create mode 100644 backend/code.c create mode 100644 backend/code1.c create mode 100644 backend/code1.h create mode 100644 backend/code128.c create mode 100644 backend/code16k.c create mode 100644 backend/code49.c create mode 100644 backend/code49.h create mode 100644 backend/common.c create mode 100644 backend/common.h create mode 100644 backend/composite.c create mode 100644 backend/composite.h create mode 100644 backend/dllversion.c create mode 100644 backend/dm200.c create mode 100644 backend/dm200.h create mode 100644 backend/dmatrix.c create mode 100644 backend/dmatrix.h create mode 100644 backend/font.h create mode 100644 backend/gb2312.h create mode 100644 backend/gridmtx.c create mode 100644 backend/gridmtx.h create mode 100644 backend/gs1.c create mode 100644 backend/gs1.h create mode 100644 backend/imail.c create mode 100644 backend/large.c create mode 100644 backend/large.h create mode 100644 backend/library.c create mode 100644 backend/libzint.rc create mode 100644 backend/maxicode.c create mode 100644 backend/maxicode.h create mode 100644 backend/maxipng.h create mode 100644 backend/medical.c create mode 100644 backend/ms_stdint.h create mode 100644 backend/pdf417.c create mode 100644 backend/pdf417.h create mode 100644 backend/plessey.c create mode 100644 backend/png.c create mode 100644 backend/postal.c create mode 100644 backend/ps.c create mode 100644 backend/qr.c create mode 100644 backend/qr.h create mode 100644 backend/reedsol.c create mode 100644 backend/reedsol.h create mode 100644 backend/rss.c create mode 100644 backend/rss.h create mode 100644 backend/sjis.h create mode 100644 backend/svg.c create mode 100644 backend/telepen.c create mode 100644 backend/upcean.c create mode 100644 backend/zint.h create mode 100644 backend_qt4/CMakeLists.txt create mode 100644 backend_qt4/QtZint2.sln create mode 100644 backend_qt4/QtZint2.vcproj create mode 100644 backend_qt4/backend_qt4.pro create mode 100644 backend_qt4/backend_vc8.pro create mode 100644 backend_qt4/qzint.cpp create mode 100644 backend_qt4/qzint.h create mode 100644 backend_qt4/readme create mode 100644 cmake/modules/FindQr.cmake create mode 100644 cmake/modules/FindZint.cmake create mode 100644 cmake_uninstall.cmake.in create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libqzint-dev.install create mode 100644 debian/libqzint.install create mode 100644 debian/libzint-dev.install create mode 100644 debian/libzint.install create mode 100644 debian/qzintfrontend.install create mode 100755 debian/rules create mode 100644 debian/zintfrontend.install create mode 100644 docs/README create mode 100644 frontend/CMakeLists.txt create mode 100644 frontend/Makefile create mode 100644 frontend/Makefile.mingw create mode 100644 frontend/getopt.c create mode 100644 frontend/getopt.h create mode 100644 frontend/getopt1.c create mode 100644 frontend/main.c create mode 100755 frontend/test.sh create mode 100644 frontend/zint.rc create mode 100644 frontend/zint_black.ico create mode 100644 frontend_qt4/CMakeLists.txt create mode 100644 frontend_qt4/barcodeitem.cpp create mode 100644 frontend_qt4/barcodeitem.h create mode 100644 frontend_qt4/datawindow.cpp create mode 100644 frontend_qt4/datawindow.h create mode 100644 frontend_qt4/exportwindow.cpp create mode 100644 frontend_qt4/exportwindow.h create mode 100644 frontend_qt4/extData.ui create mode 100644 frontend_qt4/extExport.ui create mode 100644 frontend_qt4/extSequence.ui create mode 100644 frontend_qt4/frontend_qt4.pro create mode 100644 frontend_qt4/frontend_vc8.pro create mode 100644 frontend_qt4/grpAztec.ui create mode 100644 frontend_qt4/grpC128.ui create mode 100644 frontend_qt4/grpC16k.ui create mode 100644 frontend_qt4/grpC39.ui create mode 100644 frontend_qt4/grpC49.ui create mode 100644 frontend_qt4/grpChannel.ui create mode 100644 frontend_qt4/grpCodablock.ui create mode 100644 frontend_qt4/grpCodeOne.ui create mode 100644 frontend_qt4/grpDBExtend.ui create mode 100644 frontend_qt4/grpDM.ui create mode 100644 frontend_qt4/grpGrid.ui create mode 100644 frontend_qt4/grpMQR.ui create mode 100644 frontend_qt4/grpMSICheck.ui create mode 100644 frontend_qt4/grpMaxicode.ui create mode 100644 frontend_qt4/grpMicroPDF.ui create mode 100644 frontend_qt4/grpPDF417.ui create mode 100644 frontend_qt4/grpQR.ui create mode 100644 frontend_qt4/images/.directory create mode 100644 frontend_qt4/images/rotateleft.png create mode 100644 frontend_qt4/images/rotateright.png create mode 100644 frontend_qt4/images/zint.png create mode 100644 frontend_qt4/images/zoomin.png create mode 100644 frontend_qt4/images/zoomout.png create mode 100644 frontend_qt4/main.cpp create mode 100644 frontend_qt4/mainWindow.ui create mode 100644 frontend_qt4/mainwindow.cpp create mode 100644 frontend_qt4/mainwindow.h create mode 100644 frontend_qt4/qtZint.sln create mode 100644 frontend_qt4/qtZint.vcproj create mode 100644 frontend_qt4/res/.directory create mode 100644 frontend_qt4/res/qtZint.rc create mode 100644 frontend_qt4/res/zint.ico create mode 100644 frontend_qt4/resources.qrc create mode 100644 frontend_qt4/sequencewindow.cpp create mode 100644 frontend_qt4/sequencewindow.h create mode 100644 gpl-3.0.txt create mode 100644 readme create mode 100644 readme-cmake create mode 100644 win32/libzint.vcproj create mode 100755 win32/test.bat create mode 100644 win32/zint.sln create mode 100644 win32/zint.vcproj create mode 100644 zint-qt.desktop create mode 100644 zint.nsi create mode 100644 zint.png create mode 100644 zint.spec diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..09f42f45 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,97 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +cmake_minimum_required(VERSION 2.6) +project(zint-package) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +#set(CMAKE_VERBOSE_MAKEFILE ON) +#comment or remove the above line before release + +set (ZINT_VERSION_MAJOR 2) +set (ZINT_VERSION_MINOR 3) +set (ZINT_VERSION_RELEASE 2) +set (ZINT_VERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}.${ZINT_VERSION_RELEASE}" ) + +add_definitions (-DZINT_VERSION=\"${ZINT_VERSION}\" -Wall) + +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ) + +include (SetPaths.cmake) + +INCLUDE (CheckCXXCompilerFlag) + +if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) + if (CXX_COMPILER_FLAG_WALL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif (CXX_COMPILER_FLAG_WALL) +endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + + +IF(APPLE) + IF (UNIVERSAL) # TODO: make univeral binary + IF(NOT ZINT_HAS_BEEN_RUN_BEFORE and UNIVERAL) + IF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) + SET(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64" CACHE STRING "Build architectures for OSX" FORCE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING "Flags used by the compiler during all build types." FORCE) + ELSE(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) + IF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) + SET(CMAKE_OSX_ARCHITECTURES "ppc;i386" CACHE STRING "Build architectures for OSX" FORCE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING "Flags used by the compiler during all build types." FORCE) + ENDIF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) + ENDIF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) + message("Build architectures for OSX:${CMAKE_OSX_ARCHITECTURES}") + ENDIF(NOT ZINT_HAS_BEEN_RUN_BEFORE) + + ELSE (UNIVERSAL) + SET(CMAKE_OSX_SYSROOT "/") + ENDIF (UNIVERSAL) + + IF (PNG_FOUND) + INCLUDE_DIRECTORIES( + "${PNG_INCLUDE_DIR}" + ) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpng") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lpng") + SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -lpng") + ENDIF (PNG_FOUND) + +ENDIF(APPLE) + +add_subdirectory(backend) +add_subdirectory(frontend) + +find_package(Qt4) + +if (QT4_FOUND) + set( QT_USE_QTGUI TRUE ) + set( QT_USE_QTUITOOLS TRUE ) + set( QT_USE_QTXML TRUE ) + include( ${QT_USE_FILE} ) + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${QT_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + add_subdirectory(backend_qt4) + add_subdirectory(frontend_qt4) +endif(QT4_FOUND) + +CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +ADD_CUSTOM_TARGET(uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + +install(FILES cmake/modules/FindZint.cmake DESTINATION ${CMAKE_ROOT}/Modules COMPONENT Devel) + +# This needs to be run very last so other parts of the scripts can take +# advantage of this. +IF(NOT ZINT_HAS_BEEN_RUN_BEFORE) + SET(ZINT_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before") +ENDIF(NOT ZINT_HAS_BEEN_RUN_BEFORE) + + diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..6af56d44 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Make libzint and zint together + +zint: + $(MAKE) -C backend/ + $(MAKE) -C frontend/ + +install: + $(MAKE) install -C backend/ + $(MAKE) install -C frontend/ + +uninstall: + $(MAKE) uninstall -C frontend/ + $(MAKE) uninstall -C backend/ + +clean: + $(MAKE) clean -C backend/ + $(MAKE) clean -C frontend/ + diff --git a/SetPaths.cmake b/SetPaths.cmake new file mode 100644 index 00000000..38b9d74b --- /dev/null +++ b/SetPaths.cmake @@ -0,0 +1,255 @@ +# - Find include and library dirs, and define a some macros +# +# This module defines a bunch of variables used as locations for install directories. +# They can be relative (to CMAKE_INSTALL_PREFIX) or absolute. +# Under Windows they are always relative. +# +# BIN_INSTALL_DIR - the directory where executables will be installed (default is prefix/bin) +# BUNDLE_INSTALL_DIR - Mac only: the directory where application bundles will be installed (default is /Applications/KDE4 ) +# SBIN_INSTALL_DIR - the directory where system executables will be installed (default is prefix/sbin) +# LIB_INSTALL_DIR - the directory where libraries will be installed (default is prefix/lib) +# CONFIG_INSTALL_DIR - the config file install dir +# DATA_INSTALL_DIR - the parent directory where applications can install their data +# HTML_INSTALL_DIR - the HTML install dir for documentation +# ICON_INSTALL_DIR - the icon install dir (default prefix/share/icons/) +# INFO_INSTALL_DIR - the kde info install dir (default prefix/info) +# KCFG_INSTALL_DIR - the install dir for kconfig files +# LOCALE_INSTALL_DIR - the install dir for translations +# MAN_INSTALL_DIR - the kde man page install dir (default prefix/man/) +# MIME_INSTALL_DIR - the install dir for the mimetype desktop files +# PLUGIN_INSTALL_DIR - the subdirectory relative to the install prefix where plugins will be installed (default is ${KDE4_LIB_INSTALL_DIR}/kde4) +# SERVICES_INSTALL_DIR - the install dir for service (desktop, protocol, ...) files +# SERVICETYPES_INSTALL_DIR - the install dir for servicestypes desktop files +# SOUND_INSTALL_DIR - the install dir for sound files +# TEMPLATES_INSTALL_DIR - the install dir for templates (Create new file...) +# WALLPAPER_INSTALL_DIR - the install dir for wallpapers +# DEMO_INSTALL_DIR - the install dir for demos +# KCONF_UPDATE_INSTALL_DIR - the kconf_update install dir +# XDG_APPS_INSTALL_DIR - the XDG apps dir +# XDG_DIRECTORY_INSTALL_DIR- the XDG directory +# XDG_MIME_INSTALL_DIR - the XDG mimetypes install dir +# DBUS_INTERFACES_INSTALL_DIR - the directory where dbus interfaces be installed (default is prefix/share/dbus-1/interfaces) +# DBUS_SERVICES_INSTALL_DIR - the directory where dbus services be installed (default is prefix/share/dbus-1/services ) +# +# A note on the possible values for CMAKE_BUILD_TYPE and how KDE handles +# the flags for those buildtypes. FindKDE4Internal supports the values +# Debug, Release, Relwithdebinfo, Profile and Debugfull +# +# Release +# optimised for speed, qDebug/kDebug turned off, no debug symbols +# Release with debug info +# optimised for speed, debugging symbols on (-g) +# Debug +# optimised but debuggable, debugging on (-g) +# (-fno-reorder-blocks -fno-schedule-insns -fno-inline) +# DebugFull +# no optimisation, full debugging on (-g3) +# Profile +# DebugFull + -ftest-coverage -fprofile-arcs +# +# It is expected that the "Debug" build type be still debuggable with gdb +# without going all over the place, but still produce better performance. +# It's also important to note that gcc cannot detect all warning conditions +# unless the optimiser is active. +# + +# Copyright (c) 2006-2008, Alexander Neundorf +# Copyright (c) 2006, Laurent Montel, +# Copyright (c) 2008, BogDan Vatra, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + + +########## the following are directories where stuff will be installed to ########### +# +# this has to be after find_xxx() block above + +if (WIN32) +# use relative install prefix to avoid hardcoded install paths in cmake_install.cmake files + + set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}) + + set(EXEC_INSTALL_PREFIX "" ) # Base directory for executables and libraries + set(SHARE_INSTALL_PREFIX "share" ) # Base directory for files which go to share/ + set(BIN_INSTALL_DIR "bin" ) # The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin) + set(SBIN_INSTALL_DIR "sbin" ) # The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin) + + set(LIBEXEC_INSTALL_DIR "${BIN_INSTALL_DIR}" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${BIN_INSTALL_DIR}) + set(INCLUDE_INSTALL_DIR "include" ) # The subdirectory to the header prefix + + set(PLUGIN_INSTALL_DIR "lib${LIB_SUFFIX}/kde4" ) # "The subdirectory relative to the install prefix where plugins will be installed (default is ${LIB_INSTALL_DIR}/kde4) + set(CONFIG_INSTALL_DIR "share/config" ) # The config file install dir + set(DATA_INSTALL_DIR "share/apps" ) # The parent directory where applications can install their data + set(HTML_INSTALL_DIR "share/doc/HTML" ) # The HTML install dir for documentation + set(ICON_INSTALL_DIR "share/icons" ) # The icon install dir (default ${SHARE_INSTALL_PREFIX}/share/icons/) + set(KCFG_INSTALL_DIR "share/config.kcfg" ) # The install dir for kconfig files + set(LOCALE_INSTALL_DIR "share/locale" ) # The install dir for translations + set(MIME_INSTALL_DIR "share/mimelnk" ) # The install dir for the mimetype desktop files + set(SERVICES_INSTALL_DIR "share/kde4/services" ) # The install dir for service (desktop, protocol, ...) files + set(SERVICETYPES_INSTALL_DIR "share/kde4/servicetypes" ) # The install dir for servicestypes desktop files + set(SOUND_INSTALL_DIR "share/sounds" ) # The install dir for sound files + set(TEMPLATES_INSTALL_DIR "share/templates" ) # The install dir for templates (Create new file...) + set(WALLPAPER_INSTALL_DIR "share/wallpapers" ) # The install dir for wallpapers + set(DEMO_INSTALL_DIR "share/demos" ) # The install dir for demos + set(KCONF_UPDATE_INSTALL_DIR "share/apps/kconf_update" ) # The kconf_update install dir + set(AUTOSTART_INSTALL_DIR "share/autostart" ) # The install dir for autostart files + + set(XDG_APPS_INSTALL_DIR "share/applications/kde4" ) # The XDG apps dir + set(XDG_DIRECTORY_INSTALL_DIR "share/desktop-directories" ) # The XDG directory + set(XDG_MIME_INSTALL_DIR "share/mime/packages" ) # The install dir for the xdg mimetypes + + set(SYSCONF_INSTALL_DIR "etc" ) # The kde sysconfig install dir (default /etc) + set(MAN_INSTALL_DIR "share/man" ) # The kde man install dir (default ${SHARE_INSTALL_PREFIX}/man/) + set(INFO_INSTALL_DIR "share/info" ) # The kde info install dir (default ${SHARE_INSTALL_PREFIX}/info)") + set(DBUS_INTERFACES_INSTALL_DIR "share/dbus-1/interfaces" ) # The kde dbus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)") + set(DBUS_SERVICES_INSTALL_DIR "share/dbus-1/services" ) # The kde dbus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)") + +else (WIN32) + + # This macro implements some very special logic how to deal with the cache. + # By default the various install locations inherit their value from their "parent" variable + # so if you set CMAKE_INSTALL_PREFIX, then EXEC_INSTALL_PREFIX, PLUGIN_INSTALL_DIR will + # calculate their value by appending subdirs to CMAKE_INSTALL_PREFIX . + # This would work completely without using the cache. + # But if somebody wants e.g. a different EXEC_INSTALL_PREFIX this value has to go into + # the cache, otherwise it will be forgotten on the next cmake run. + # Once a variable is in the cache, it doesn't depend on its "parent" variables + # anymore and you can only change it by editing it directly. + # this macro helps in this regard, because as long as you don't set one of the + # variables explicitely to some location, it will always calculate its value from its + # parents. So modifying CMAKE_INSTALL_PREFIX later on will have the desired effect. + # But once you decide to set e.g. EXEC_INSTALL_PREFIX to some special location + # this will go into the cache and it will no longer depend on CMAKE_INSTALL_PREFIX. + # + # additionally if installing to the same location as kdelibs, the other install + # directories are reused from the installed kdelibs + macro(_SET_FANCY _var _value _comment) + set(predefinedvalue "${_value}") + + if (NOT DEFINED ${_var}) + set(${_var} ${predefinedvalue}) + else (NOT DEFINED ${_var}) + set(${_var} "${${_var}}" CACHE PATH "${_comment}") + endif (NOT DEFINED ${_var}) + endmacro(_SET_FANCY) + + if(APPLE) + set(BUNDLE_INSTALL_DIR "/Applications/KDE4" CACHE PATH "Directory where application bundles will be installed to on OSX" ) + endif(APPLE) + + _set_fancy(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Base directory for executables and libraries") + _set_fancy(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share" "Base directory for files which go to share/") + _set_fancy(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" "The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)") + _set_fancy(SBIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/sbin" "The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin)") + _set_fancy(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" "The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})") + _set_fancy(LIBEXEC_INSTALL_DIR "${LIB_INSTALL_DIR}/kde4/libexec" "The subdirectory relative to the install prefix where libraries will be installed (default is ${LIB_INSTALL_DIR}/kde4/libexec)") + _set_fancy(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" "The subdirectory to the header prefix") + + _set_fancy(PLUGIN_INSTALL_DIR "${LIB_INSTALL_DIR}/kde4" "The subdirectory relative to the install prefix where plugins will be installed (default is ${LIB_INSTALL_DIR}/kde4)") + _set_fancy(CONFIG_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/config" "The config file install dir") + _set_fancy(DATA_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/apps" "The parent directory where applications can install their data") + _set_fancy(HTML_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/doc/HTML" "The HTML install dir for documentation") + _set_fancy(ICON_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/icons" "The icon install dir (default ${SHARE_INSTALL_PREFIX}/share/icons/)") + _set_fancy(KCFG_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/config.kcfg" "The install dir for kconfig files") + _set_fancy(LOCALE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/locale" "The install dir for translations") + _set_fancy(MIME_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/mimelnk" "The install dir for the mimetype desktop files") + _set_fancy(SERVICES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/kde4/services" "The install dir for service (desktop, protocol, ...) files") + _set_fancy(SERVICETYPES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/kde4/servicetypes" "The install dir for servicestypes desktop files") + _set_fancy(SOUND_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/sounds" "The install dir for sound files") + _set_fancy(TEMPLATES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/templates" "The install dir for templates (Create new file...)") + _set_fancy(WALLPAPER_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/wallpapers" "The install dir for wallpapers") + _set_fancy(DEMO_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/demos" "The install dir for demos") + _set_fancy(KCONF_UPDATE_INSTALL_DIR "${DATA_INSTALL_DIR}/kconf_update" "The kconf_update install dir") + _set_fancy(AUTOSTART_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/autostart" "The install dir for autostart files") + + _set_fancy(XDG_APPS_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/applications/kde4" "The XDG apps dir") + _set_fancy(XDG_DIRECTORY_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/desktop-directories" "The XDG directory") + _set_fancy(XDG_MIME_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/mime/packages" "The install dir for the xdg mimetypes") + + _set_fancy(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc" "The kde sysconfig install dir (default ${CMAKE_INSTALL_PREFIX}/etc)") + _set_fancy(MAN_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/man" "The kde man install dir (default ${SHARE_INSTALL_PREFIX}/man/)") + _set_fancy(INFO_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/info" "The kde info install dir (default ${SHARE_INSTALL_PREFIX}/info)") + _set_fancy(DBUS_INTERFACES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/interfaces" "The kde dbus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)") + _set_fancy(DBUS_SERVICES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/services" "The kde dbus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)") + +endif (WIN32) + + +# The INSTALL_TARGETS_DEFAULT_ARGS variable should be used when libraries are installed. +# The arguments are also ok for regular executables, i.e. executables which don't go +# into sbin/ or libexec/, but for installing executables the basic syntax +# INSTALL(TARGETS kate DESTINATION "${BIN_INSTALL_DIR}") +# is enough, so using this variable there doesn't help a lot. +# The variable must not be used for installing plugins. +# Usage is like this: +# install(TARGETS kdecore kdeui ${INSTALL_TARGETS_DEFAULT_ARGS} ) +# +# This will install libraries correctly under UNIX, OSX and Windows (i.e. dll's go +# into bin/. +# Later on it will be possible to extend this for installing OSX frameworks +# The COMPONENT Devel argument has the effect that static libraries belong to the +# "Devel" install component. If we use this also for all install() commands +# for header files, it will be possible to install +# -everything: make install OR cmake -P cmake_install.cmake +# -only the development files: cmake -DCOMPONENT=Devel -P cmake_install.cmake +# -everything except the development files: cmake -DCOMPONENT=Unspecified -P cmake_install.cmake +# This can then also be used for packaging with cpack. + +set(INSTALL_TARGETS_DEFAULT_ARGS RUNTIME DESTINATION "${BIN_INSTALL_DIR}" + LIBRARY DESTINATION "${LIB_INSTALL_DIR}" + ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" COMPONENT Devel ) + + + +# on the Mac support an extra install directory for application bundles starting with cmake 2.6 +if(APPLE) + set(INSTALL_TARGETS_DEFAULT_ARGS ${INSTALL_TARGETS_DEFAULT_ARGS} + BUNDLE DESTINATION "${BUNDLE_INSTALL_DIR}" ) +endif(APPLE) + + +set(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} + "${INCLUDE_INSTALL_DIR}") + +set(CMAKE_SYSTEM_PROGRAM_PATH ${CMAKE_SYSTEM_PROGRAM_PATH} + "${BIN_INSTALL_DIR}" ) + +set(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} + "${LIB_INSTALL_DIR}" ) + +# under Windows dlls may be also installed in bin/ +if(WIN32) + set(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} + "${_CMAKE_INSTALL_DIR}/bin" + "${CMAKE_INSTALL_PREFIX}/bin" ) +endif(WIN32) + + +###################################################### +# and now the platform specific stuff +###################################################### + +# Set a default build type for single-configuration +# CMake generators if no build type is set. +if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo) +endif (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + + + +# setup default RPATH/install_name handling, may be overridden by KDE4_HANDLE_RPATH_FOR_[LIBRARY|EXECUTABLE] +# default is to build with RPATH for the install dir, so it doesn't need to relink +if (UNIX) + if (APPLE) + set(CMAKE_INSTALL_NAME_DIR ${LIB_INSTALL_DIR}) + else (APPLE) + # add our LIB_INSTALL_DIR to the RPATH and use the RPATH figured out by cmake when compiling + set(CMAKE_INSTALL_RPATH ${LIB_INSTALL_DIR} ) + set(CMAKE_SKIP_BUILD_RPATH TRUE) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + endif (APPLE) +endif (UNIX) + diff --git a/backend/2of5.c b/backend/2of5.c new file mode 100644 index 00000000..38700cde --- /dev/null +++ b/backend/2of5.c @@ -0,0 +1,363 @@ +/* 2of5.c - Handles Code 2 of 5 barcodes */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include +#include "common.h" +#ifdef _MSC_VER +#include +#endif + +static char *C25MatrixTable[10] = {"113311", "311131", "131131", "331111", "113131", "313111", + "133111", "111331", "311311", "131311"}; + +static char *C25IndustTable[10] = {"1111313111", "3111111131", "1131111131", "3131111111", "1111311131", + "3111311111", "1131311111", "1111113131", "3111113111", "1131113111"}; + +static char *C25InterTable[10] = {"11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133", + "31131", "13131"}; + + +int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 2 of 5 Standard (Code 2 of 5 Matrix) */ + + int i, error_number; + char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/ + + error_number = 0; + + if(length > 80) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "411111"); + + for(i = 0; i < length; i++) { + lookup(NEON, C25MatrixTable, source[i], dest); + } + + /* Stop character */ + concat (dest, "41111"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 2 of 5 Industrial */ + + int i, error_number; + char dest[512]; /* 6 + 40 * 10 + 6 + 1 */ + + error_number = 0; + + if(length > 45) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid character in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "313111"); + + for(i = 0; i < length; i++) { + lookup(NEON, C25IndustTable, source[i], dest); + } + + /* Stop character */ + concat (dest, "31113"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 2 of 5 IATA */ + int i, error_number; + char dest[512]; /* 4 + 45 * 10 + 3 + 1 */ + + error_number = 0; + + if(length > 45) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* start */ + strcpy(dest, "1111"); + + for(i = 0; i < length; i++) { + lookup(NEON, C25IndustTable, source[i], dest); + } + + /* stop */ + concat (dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 2 of 5 Data Logic */ + + int i, error_number; + char dest[512]; /* 4 + 80 * 6 + 3 + 1 */ + + error_number = 0; + + if(length > 80) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "1111"); + + for(i = 0; i < length; i++) { + lookup(NEON, C25MatrixTable, source[i], dest); + } + + /* Stop character */ + concat (dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 2 of 5 Interleaved */ + + int i, j, k, error_number; + char bars[7], spaces[7], mixed[14], dest[1000]; +#ifndef _MSC_VER + unsigned char temp[length + 2]; +#else + unsigned char* temp = (unsigned char *)_alloca((length + 2) * sizeof(unsigned char)); +#endif + + error_number = 0; + + if(length > 89) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + ustrcpy(temp, (unsigned char *) ""); + /* Input must be an even number of characters for Interlaced 2 of 5 to work: + if an odd number of characters has been entered then add a leading zero */ + if ((length % 2) != 0) + { + ustrcpy(temp, (unsigned char *) "0"); + length++; + } + uconcat(temp, source); + + /* start character */ + strcpy(dest, "1111"); + + for(i = 0; i < length; i+=2 ) + { + /* look up the bars and the spaces and put them in two strings */ + strcpy(bars, ""); + lookup(NEON, C25InterTable, temp[i], bars); + strcpy(spaces, ""); + lookup(NEON, C25InterTable, temp[i + 1], spaces); + + /* then merge (interlace) the strings together */ + k = 0; + for(j = 0; j <= 4; j++) + { + mixed[k] = bars[j]; k++; + mixed[k] = spaces[j]; k++; + } + mixed[k] = '\0'; + concat (dest, mixed); + } + + /* Stop character */ + concat (dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, temp); + return error_number; + +} + +int itf14(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int i, error_number, zeroes; + unsigned int count, check_digit; + char localstr[16]; + + error_number = 0; + + count = 0; + + if(length > 13) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid character in data"); + return error_number; + } + + /* Add leading zeros as required */ + zeroes = 13 - length; + for(i = 0; i < zeroes; i++) { + localstr[i] = '0'; + } + strcpy(localstr + zeroes, (char *)source); + + /* Calculate the check digit - the same method used for EAN-13 */ + + for (i = 12; i >= 0; i--) + { + count += ctoi(localstr[i]); + + if ((i%2) == 0) + { + count += 2 * ctoi(localstr[i]); + } + } + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + localstr[13] = itoc(check_digit); + localstr[14] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*)localstr); + return error_number; +} + +int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Deutshe Post Leitcode */ + int i, error_number; + unsigned int count, check_digit; + char localstr[16]; + int zeroes; + + error_number = 0; + count = 0; + if(length > 13) { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + zeroes = 13 - length; + for(i = 0; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *)source); + + for (i = 12; i >= 0; i--) + { + count += 4 * ctoi(localstr[i]); + + if (!((i%2) == 0)) + { + count += 5 * ctoi(localstr[i]); + } + } + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + localstr[13] = itoc(check_digit); + localstr[14] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*)localstr); + return error_number; +} + +int dpident(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Deutsche Post Identcode */ + int i, error_number, zeroes; + unsigned int count, check_digit; + char localstr[16]; + + count = 0; + if(length > 11) { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + zeroes = 11 - length; + for(i = 0; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *)source); + + for (i = 10; i >= 0; i--) + { + count += 4 * ctoi(localstr[i]); + + if (!((i%2) == 0)) + { + count += 5 * ctoi(localstr[i]); + } + } + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + localstr[11] = itoc(check_digit); + localstr[12] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*)localstr); + return error_number; +} diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt new file mode 100644 index 00000000..57a819ed --- /dev/null +++ b/backend/CMakeLists.txt @@ -0,0 +1,27 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(zint) + +find_package(PNG) + +set(zint_COMMON_SRCS common.c library.c ps.c large.c reedsol.c gs1.c svg.c png.c) +set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c) +set(zint_POSTAL_SRCS postal.c auspost.c imail.c) +set(zint_TWODIM_SRCS code16k.c dmatrix.c dm200.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c) +set(zint_SRCS ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS} ) + +if(PNG_FOUND) + include_directories( ${PNG_INCLUDES} ) +else(PNG_FOUND) + add_definitions (-DNO_PNG) +endif(PNG_FOUND) + +add_library(zint SHARED ${zint_SRCS}) + +set_target_properties(zint PROPERTIES SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}" + VERSION ${ZINT_VERSION}) + +target_link_libraries(zint ${PNG_LIBRARIES} ) + +install(TARGETS zint ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) diff --git a/backend/DEVELOPER b/backend/DEVELOPER new file mode 100644 index 00000000..30eb52e2 --- /dev/null +++ b/backend/DEVELOPER @@ -0,0 +1,133 @@ +Contents +-------- + +Here is a guide to which bit of source code does what. + +2of5.c: + Matrix 2 of 5 + Industrial 2 of 5 + IATA 2 of 5 + Data Logic + Interleaved 2 of 5 + ITF-14 + Deutche Post Leitcode + Deutche Post Identcode + +auspost.c: + Australia Post Standard Customer Barcode + Australia Post Customer Barcode 2 + Australia Post Customer Barcode 3 + Australia Post Reply Paid Barcode + Australia Post Routing Barcode + Australia Post Redirect Barcode + +aztec.c: + Aztec Code + Compact Aztec Code + Aztec Runes + +blockf.c: + Codablock-F + +code128.c: + Code 128 + Code 128 Subset B + NVE-18 + GS1-128 (UCC/EAN-128) + EAN-14 + +code16k.c: + Code 16k + +code.c: + Code 11 + Code 39 + Pharmazentral Nummer (PZN) + Extended Code 39 (Code 39+) + Code 93 + LOGMARS + Channel Code + +code1.c: + Code One + +code49.c: + Code 49 + +composite.c: + CC-A Composite Symbology + CC-B Composite Symbology + CC-C Composite Symbology + +dm200.c: + Data Matrix ECC 200 + +dmatrix.c: + Data Matrix ECC 000 + Data Matrix ECC 050 + Data Matrix ECC 080 + Data Matrix ECC 100 + Data Matrix ECC 140 + +gridmtx.c: + Grid Matrix + +imail.c: + USPS OneCode (Intelligent Mail) + +maxicode.c: + UPS Maxicode + +medical.c: + Pharma Code + Two Track Pharma Code + Codabar + Code 32 + +pdf417.c: + PDF417 + Truncated PDF417 + MicroPDF417 + +plessey.c: + UK Plessey Code (bidirectional) + MSI Plessey + +postal.c: + PostNet + PLANET + Facing Identification Mark (FIM) + Royal Mail 4-State Country Code (RM4SCC) + KIX Code + DAFT Code + Flattermarken + Korean Postal Code + Japanese Postal Code + +qr.c: + QR Code + Micro QR Code + +rss.c: + GS1 DataBar (DataBar-14) (RSS-14) + GS1 DataBar Stacked (RSS-14 Stacked) + GS1 DataBar Stacked Omnidirectional (DataBar-14 Stacked Omnidirectional) + (RSS-14 Stacked Omnidirectional) + GS1 DataBar Limited (RSS Limited) + GS1 DataBar Expanded (RSS Expanded) + GS1 DataBar Expanded Stacked (RSS Expanded Stacked) + +telepen.c: + Telepen ASCII + Telepen Numeric + +upcean.c: + UPC-A + UPC-E + EAN-2 add-on + EAN-5 add-on + EAN-8 + EAN-13 + SBN (verification) + ISBN (verification) + ISBN-13 (verification) \ No newline at end of file diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 00000000..a27179c5 --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,54 @@ +# Linux makefile for libzint +# +# make compiles +# make install copies to /usr/local/lib +# make uninstall removes library +# make clean cleans up a previous compilation and any object or editor files +# + +ZINT_VERSION:=-DZINT_VERSION=\"2.3.2\" + + +CC := gcc +INCLUDE := -I/usr/include +CFLAGS := -g + +prefix := /usr +includedir := $(prefix)/include +libdir := $(prefix)/lib +DESTDIR := + +COMMON:= common.c png.c library.c ps.c large.c reedsol.c gs1.c svg.c +COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o +ONEDIM:= code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c +ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o +POSTAL:= postal.c auspost.c imail.c +POSTAL_OBJ:= postal.o auspost.o imail.o +TWODIM:= code16k.c dmatrix.c dm200.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c +TWODIM_OBJ:= code16k.o dmatrix.o dm200.o pdf417.o qr.o maxicode.o composite.o aztec.o code49.o code1.o gridmtx.o +LIBS:= `libpng12-config --I_opts --L_opts --ldflags` -lz -lm + +libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c aztec.c gs1.c svg.c code49.c code1.c gridmtx.c + $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(ONEDIM) + $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(POSTAL) + $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(TWODIM) + $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(COMMON) + $(CC) $(CFLAGS) $(ZINT_VERSION) -shared -Wl,-soname,libzint.so -o libzint.so.2.3.2 $(INCLUDE) $(COMMON_OBJ) $(ONEDIM_OBJ) $(TWODIM_OBJ) $(POSTAL_OBJ) $(LIBS) + ln -s libzint.so.* libzint.so + +.PHONY: install uninstall clean dist + +install: + test "$(UID)" = "0" && ldconfig -n $(PWD) || true + install -d $(DESTDIR)$(libdir) + mv libzint.* $(DESTDIR)$(libdir) + install -D -p --mode=0644 zint.h $(DESTDIR)$(includedir)/zint.h + +uninstall: + rm $(DESTDIR)$(libdir)/libzint.* + rm $(DESTDIR)$(includedir)/zint.h + +clean: + rm -f libzint.* *.o *.a *~ + + diff --git a/backend/Makefile.mingw b/backend/Makefile.mingw new file mode 100644 index 00000000..5cb0e83b --- /dev/null +++ b/backend/Makefile.mingw @@ -0,0 +1,79 @@ +# Linux makefile for libzint +# +# make compiles with QR Code support +# make install copies to /usr/lib +# make uninstall removes library +# make clean cleans up a previous compilation and any object or editor files +# + +ZINT_VERSION:=-DZINT_VERSION=\"2.3.2\" + + +CC:= gcc +AR:= ar rc +RANLIB:= ranlib +INCLUDE:= -I/mingw/include +CFLAGS:= -D_WIN32 -O2 -fms-extensions -mms-bitfields -fno-exceptions -fomit-frame-pointer -Wall + +prefix := /mingw +includedir := $(prefix)/include +libdir := $(prefix)/lib +bindir := $(prefix)/bin +DESTDIR := +APP:=zint +DLL:=$(APP).dll +STATLIB:=lib$(APP).a + +COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o +ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o +POSTAL_OBJ:= postal.o auspost.o imail.o +TWODIM_OBJ:= code16k.o dmatrix.o dm200.o pdf417.o qr.o maxicode.o composite.o aztec.o code49.o code1.o gridmtx.o + +LIB_OBJ:= $(COMMON_OBJ) $(ONEDIM_OBJ) $(TWODIM_OBJ) $(POSTAL_OBJ) +DLL_OBJ:= $(LIB_OBJ:.o=.lo) dllversion.lo + + +ifeq ($(NO_PNG),true) +DEFINES+= -DNO_PNG +else +DEFINES_DLL+= -DPNG_DLL -DZLIB_DLL +LIBS+= -lpng -lz +endif + +LIBS+= -lm + +all: $(DLL) $(STATLIB) + +%.lo:%.c + @echo Compiling $< ... + $(CC) $(CFLAGS) $(DEFINES) $(DEFINES_DLL) -DDLL_EXPORT -DPIC $(ZINT_VERSION) -c -o $@ $< + +%.o:%.c + @echo Compiling $< ... + $(CC) $(CFLAGS) $(DEFINES) $(ZINT_VERSION) -c -o $@ $< + +$(DLL):$(DLL_OBJ) + @echo Linking $@... + o2dll.sh -o $@ $(DLL_OBJ) $(LIBS) + +$(STATLIB): $(LIB_OBJ) + @echo Linking $@... + $(AR) $@ $(LIB_OBJ) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +.PHONY: install uninstall clean dist + +install: + cp -fp libzint.* $(DESTDIR)$(libdir) + cp -fp zint.h $(DESTDIR)$(includedir)/zint.h + cp -fp zint.dll $(DESTDIR)$(bindir) + +uninstall: + rm $(DESTDIR)$(libdir)/libzint.* + rm $(DESTDIR)$(includedir)/zint.h + rm $(DESTDIR)$(bindir)/zint.dll + +clean: + rm -f *.lib *.dll *.o *.a *~ *.res *.exe *.def *.lo *.bak + + diff --git a/backend/auspost.c b/backend/auspost.c new file mode 100644 index 00000000..c19c377c --- /dev/null +++ b/backend/auspost.c @@ -0,0 +1,248 @@ +/* auspost.c - Handles Australia Post 4-State Barcode */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +#define GDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" + +static char *AusNTable[10] = {"00", "01", "02", "10", "11", "12", "20", "21", "22", "30"}; + +static char *AusCTable[64] = {"222", "300", "301", "302", "310", "311", "312", "320", "321", "322", + "000", "001", "002", "010", "011", "012", "020", "021", "022", "100", "101", "102", "110", + "111", "112", "120", "121", "122", "200", "201", "202", "210", "211", "212", "220", "221", + "023", "030", "031", "032", "033", "103", "113", "123", "130", "131", "132", "133", "203", + "213", "223", "230", "231", "232", "233", "303", "313", "323", "330", "331", "332", "333", + "003", "013"}; + +static char *AusBarTable[64] = {"000", "001", "002", "003", "010", "011", "012", "013", "020", "021", + "022", "023", "030", "031", "032", "033", "100", "101", "102", "103", "110", "111", "112", + "113", "120", "121", "122", "123", "130", "131", "132", "133", "200", "201", "202", "203", + "210", "211", "212", "213", "220", "221", "222", "223", "230", "231", "232", "233", "300", + "301", "302", "303", "310", "311", "312", "313", "320", "321", "322", "323", "330", "331", + "332", "333"}; + +#include +#include +#include +#include "common.h" +#include "reedsol.h" + +void rs_error(char data_pattern[]) +{ + /* Adds Reed-Solomon error correction to auspost */ + + int reader, triple_writer; + char triple[31], inv_triple[31]; + unsigned char result[5]; + + triple_writer = 0; + + for(reader = 2; reader < strlen(data_pattern); reader+= 3) + { + triple[triple_writer] = 0; + switch(data_pattern[reader]) + { + case '1': triple[triple_writer] += 16; break; + case '2': triple[triple_writer] += 32; break; + case '3': triple[triple_writer] += 48; break; + } + switch(data_pattern[reader + 1]) + { + case '1': triple[triple_writer] += 4; break; + case '2': triple[triple_writer] += 8; break; + case '3': triple[triple_writer] += 12; break; + } + switch(data_pattern[reader + 2]) + { + case '1': triple[triple_writer] += 1; break; + case '2': triple[triple_writer] += 2; break; + case '3': triple[triple_writer] += 3; break; + } + triple_writer++; + + } + + for(reader = 0; reader < triple_writer; reader++) + { + inv_triple[reader] = triple[(triple_writer - 1) - reader]; + } + + rs_init_gf(0x43); + rs_init_code(4, 1); + rs_encode(triple_writer, (unsigned char*) inv_triple, result); + + for(reader = 4; reader > 0; reader--) + { + concat(data_pattern, AusBarTable[(int)result[reader - 1]]); + } + rs_free(); +} + +int australia_post(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Handles Australia Posts's 4 State Codes */ + /* Customer Standard Barcode, Barcode 2 or Barcode 3 system determined automatically + (i.e. the FCC doesn't need to be specified by the user) dependent + on the length of the input string */ + + /* The contents of data_pattern conform to the following standard: + 0 = Tracker, Ascender and Descender + 1 = Tracker and Ascender + 2 = Tracker and Descender + 3 = Tracker only */ + int error_number, zeroes; + int writer; + unsigned int loopey, reader, h; + + char data_pattern[200]; + char fcc[3], dpid[10]; + char localstr[30]; + + error_number = 0; + strcpy(localstr, ""); + + /* Do all of the length checking first to avoid stack smashing */ + if(symbol->symbology == BARCODE_AUSPOST) { + /* Format control code (FCC) */ + switch(length) + { + case 8: strcpy(fcc, "11"); break; + case 13: strcpy(fcc, "59"); break; + case 16: strcpy(fcc, "59"); error_number = is_sane(NEON, source, length); break; + case 18: strcpy(fcc, "62"); break; + case 23: strcpy(fcc, "62"); error_number = is_sane(NEON, source, length); break; + default: strcpy(symbol->errtxt, "Auspost input is wrong length"); + return ERROR_TOO_LONG; + break; + } + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + } else { + if(length > 8) { + strcpy(symbol->errtxt, "Auspost input is too long"); + return ERROR_TOO_LONG; + } + switch(symbol->symbology) { + case BARCODE_AUSREPLY: strcpy(fcc, "45"); break; + case BARCODE_AUSROUTE: strcpy(fcc, "87"); break; + case BARCODE_AUSREDIRECT: strcpy(fcc, "92"); break; + } + + /* Add leading zeros as required */ + zeroes = 8 - length; + memset(localstr, '0', zeroes); + localstr[8] = '\0'; + } + + concat(localstr, (char*)source); + h = strlen(localstr); + error_number = is_sane(GDSET, (unsigned char *)localstr, h); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* Verifiy that the first 8 characters are numbers */ + memcpy(dpid, localstr, 8); + dpid[8] = '\0'; + error_number = is_sane(NEON, (unsigned char *)dpid, strlen(dpid)); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in DPID"); + return error_number; + } + + /* Start character */ + strcpy(data_pattern, "13"); + + /* Encode the FCC */ + for(reader = 0; reader < 2; reader++) + { + lookup(NEON, AusNTable, fcc[reader], data_pattern); + } + + /* printf("AUSPOST FCC: %s ", fcc); */ + + /* Delivery Point Identifier (DPID) */ + for(reader = 0; reader < 8; reader++) + { + lookup(NEON, AusNTable, dpid[reader], data_pattern); + } + + /* Customer Information */ + if(h > 8) + { + if((h == 13) || (h == 18)) { + for(reader = 8; reader < h; reader++) { + lookup(GDSET, AusCTable, localstr[reader], data_pattern); + } + } + if((h == 16) || (h == 23)) { + for(reader = 8; reader < h; reader++) { + lookup(NEON, AusNTable, localstr[reader], data_pattern); + } + } + } + + /* Filler bar */ + h = strlen(data_pattern); + if(h == 22) { + concat(data_pattern, "3"); + } + else if(h == 37) { + concat(data_pattern, "3"); + } + else if(h == 52) { + concat(data_pattern, "3"); + } + + /* Reed Solomon error correction */ + rs_error(data_pattern); + + /* Stop character */ + concat(data_pattern, "13"); + + /* Turn the symbol into a bar pattern ready for plotting */ + writer = 0; + h = strlen(data_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((data_pattern[loopey] == '1') || (data_pattern[loopey] == '0')) + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if((data_pattern[loopey] == '2') || (data_pattern[loopey] == '0')) + { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 4; + symbol->row_height[1] = 2; + symbol->row_height[2] = 4; + + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + diff --git a/backend/aztec.c b/backend/aztec.c new file mode 100644 index 00000000..db148bdd --- /dev/null +++ b/backend/aztec.c @@ -0,0 +1,1350 @@ +/* aztec.c - Handles Aztec 2D Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "aztec.h" +#include "reedsol.h" + +void mapshorten(int *charmap, int *typemap, int start, int length) +{ /* Shorten the string by one character */ + + memmove(charmap + start + 1 , charmap + start + 2, (length - 1) * sizeof(int)); + memmove(typemap + start + 1 , typemap + start + 2, (length - 1) * sizeof(int)); +} + +void insert(char binary_string[], int posn, char newbit) +{ /* Insert a character into the middle of a string at position posn */ + int i, end; + + end = strlen(binary_string); + for(i = end; i > posn; i--) { + binary_string[i] = binary_string[i - 1]; + } + binary_string[posn] = newbit; +} + +int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1) +{ /* Encode input data into a binary string */ + int i, j, k, bytes; + int curtable, newtable, lasttable, chartype, maplength, blocks, debug; +#ifndef _MSC_VER + int charmap[src_len * 2], typemap[src_len * 2]; + int blockmap[2][src_len]; +#else + int* charmap = (int*)_alloca(src_len * 2 * sizeof(int)); + int* typemap = (int*)_alloca(src_len * 2 * sizeof(int)); + int* blockmap[2]; + blockmap[0] = (int*)_alloca(src_len * sizeof(int)); + blockmap[1] = (int*)_alloca(src_len * sizeof(int)); +#endif + /* Lookup input string in encoding table */ + maplength = 0; + debug = 0; + + for(i = 0; i < src_len; i++) { + if(gs1 && (i == 0)) { + /* Add FNC1 to beginning of GS1 messages */ + charmap[maplength] = 0; + typemap[maplength++] = PUNC; + charmap[maplength] = 400; + typemap[maplength++] = PUNC; + } + if((gs1) && (source[i] == '[')) { + /* FNC1 represented by FLG(0) */ + charmap[maplength] = 0; + typemap[maplength++] = PUNC; + charmap[maplength] = 400; + typemap[maplength++] = PUNC; + } else { + if(source[i] > 127) { + charmap[maplength] = source[i]; + typemap[maplength++] = BINARY; + } else { + charmap[maplength] = AztecSymbolChar[source[i]]; + typemap[maplength++] = AztecCodeSet[source[i]]; + } + } + } + + /* Look for double character encoding possibilities */ + i = 0; + do{ + if(((charmap[i] == 300) && (charmap[i + 1] == 11)) && ((typemap[i] == PUNC) && (typemap[i + 1] == PUNC))) { + /* CR LF combination */ + charmap[i] = 2; + typemap[i] = PUNC; + mapshorten(charmap, typemap, i, maplength); + maplength--; + } + + if(((charmap[i] == 302) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) { + /* . SP combination */ + charmap[i] = 3; + typemap[i] = PUNC; + mapshorten(charmap, typemap, i, maplength); + maplength--; + } + + if(((charmap[i] == 301) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) { + /* , SP combination */ + charmap[i] = 4; + typemap[i] = PUNC; + mapshorten(charmap, typemap, i, maplength); + maplength--; + } + + if(((charmap[i] == 21) && (charmap[i + 1] == 1)) && ((typemap[i] == PUNC) && (typemap[i + 1] == 23))) { + /* : SP combination */ + charmap[i] = 5; + typemap[i] = PUNC; + mapshorten(charmap, typemap, i, maplength); + maplength--; + } + + i++; + }while(i < (maplength - 1)); + + /* look for blocks of characters which use the same table */ + blocks = 1; + blockmap[0][0] = typemap[0]; + blockmap[1][0] = 1; + for(i = 1; i < maplength; i++) { + if(typemap[i] == typemap[i - 1]) { + blockmap[1][blocks - 1]++; + } else { + blocks++; + blockmap[0][blocks - 1] = typemap[i]; + blockmap[1][blocks - 1] = 1; + } + } + + if(blockmap[0][0] & 1) { blockmap[0][0] = 1; } + if(blockmap[0][0] & 2) { blockmap[0][0] = 2; } + if(blockmap[0][0] & 4) { blockmap[0][0] = 4; } + if(blockmap[0][0] & 8) { blockmap[0][0] = 8; } + + if(blocks > 1) { + + /* look for adjacent blocks which can use the same table (left to right search) */ + for(i = 1; i < blocks; i++) { + if(blockmap[0][i] & blockmap[0][i - 1]) { + blockmap[0][i] = (blockmap[0][i] & blockmap[0][i - 1]); + } + } + + if(blockmap[0][blocks - 1] & 1) { blockmap[0][blocks - 1] = 1; } + if(blockmap[0][blocks - 1] & 2) { blockmap[0][blocks - 1] = 2; } + if(blockmap[0][blocks - 1] & 4) { blockmap[0][blocks - 1] = 4; } + if(blockmap[0][blocks - 1] & 8) { blockmap[0][blocks - 1] = 8; } + + /* look for adjacent blocks which can use the same table (right to left search) */ + for(i = blocks - 1; i > 0; i--) { + if(blockmap[0][i] & blockmap[0][i + 1]) { + blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]); + } + } + + /* determine the encoding table for characters which do not fit with adjacent blocks */ + for(i = 1; i < blocks; i++) { + if(blockmap[0][i] & 8) { blockmap[0][i] = 8; } + if(blockmap[0][i] & 4) { blockmap[0][i] = 4; } + if(blockmap[0][i] & 2) { blockmap[0][i] = 2; } + if(blockmap[0][i] & 1) { blockmap[0][i] = 1; } + } + + /* Combine blocks of the same type */ + i = 0; + do{ + if(blockmap[0][i] == blockmap[0][i + 1]) { + blockmap[1][i] += blockmap[1][i + 1]; + for(j = i + 1; j < blocks; j++) { + blockmap[0][j] = blockmap[0][j + 1]; + blockmap[1][j] = blockmap[1][j + 1]; + } + blocks--; + } else { + i++; + } + } while (i < blocks); + } + + /* Put the adjusted block data back into typemap */ + j = 0; + for(i = 0; i < blocks; i++) { + if((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) { /* Shift character(s) needed */ + for(k = 0; k < blockmap[1][i]; k++) { + typemap[j + k] = blockmap[0][i] + 64; + } + } else { /* Latch character (or byte mode) needed */ + for(k = 0; k < blockmap[1][i]; k++) { + typemap[j + k] = blockmap[0][i]; + } + } + j += blockmap[1][i]; + } + + /* Don't shift an initial capital letter */ + if(typemap[0] == 65) { typemap[0] = 1; }; + + /* Problem characters (those that appear in different tables with different values) can now be resolved into their tables */ + for(i = 0; i < maplength; i++) { + if((charmap[i] >= 300) && (charmap[i] < 400)) { + curtable = typemap[i]; + if(curtable > 64) { + curtable -= 64; + } + switch(charmap[i]) { + case 300: /* Carriage Return */ + switch(curtable) { + case PUNC: charmap[i] = 1; break; + case MIXED: charmap[i] = 14; break; + } + break; + case 301: /* Comma */ + switch(curtable) { + case PUNC: charmap[i] = 17; break; + case DIGIT: charmap[i] = 12; break; + } + break; + case 302: /* Full Stop */ + switch(curtable) { + case PUNC: charmap[i] = 19; break; + case DIGIT: charmap[i] = 13; break; + } + break; + } + } + } + *binary_string = '\0'; + + curtable = UPPER; /* start with UPPER table */ + lasttable = UPPER; + for(i = 0; i < maplength; i++) { + newtable = curtable; + if((typemap[i] != curtable) && (charmap[i] < 400)) { + /* Change table */ + if(curtable == BINARY) { + /* If ending binary mode the current table is the same as when entering binary mode */ + curtable = lasttable; + newtable = lasttable; + } + if(typemap[i] > 64) { + /* Shift character */ + switch(typemap[i]) { + case (64 + UPPER): /* To UPPER */ + switch(curtable) { + case LOWER: /* US */ + concat(binary_string, hexbit[28]); + if(debug) printf("US "); + break; + case MIXED: /* UL */ + concat(binary_string, hexbit[29]); + if(debug) printf("UL "); + newtable = UPPER; + break; + case PUNC: /* UL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + newtable = UPPER; + break; + case DIGIT: /* US */ + concat(binary_string, pentbit[15]); + if(debug) printf("US "); + break; + } + break; + case (64 + LOWER): /* To LOWER */ + switch(curtable) { + case UPPER: /* LL */ + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case MIXED: /* LL */ + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case PUNC: /* UL LL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case DIGIT: /* UL LL */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + } + break; + case (64 + MIXED): /* To MIXED */ + switch(curtable) { + case UPPER: /* ML */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case LOWER: /* ML */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case PUNC: /* UL ML */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case DIGIT: /* UL ML */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + } + break; + case (64 + PUNC): /* To PUNC */ + switch(curtable) { + case UPPER: /* PS */ + concat(binary_string, hexbit[0]); + if(debug) printf("PS "); + break; + case LOWER: /* PS */ + concat(binary_string, hexbit[0]); + if(debug) printf("PS "); + break; + case MIXED: /* PS */ + concat(binary_string, hexbit[0]); + if(debug) printf("PS "); + break; + case DIGIT: /* PS */ + concat(binary_string, pentbit[0]); + if(debug) printf("PS "); + break; + } + break; + case (64 + DIGIT): /* To DIGIT */ + switch(curtable) { + case UPPER: /* DL */ + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case LOWER: /* DL */ + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case MIXED: /* UL DL */ + concat(binary_string, hexbit[29]); + if(debug) printf("UL "); + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case PUNC: /* UL DL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + } + break; + } + } else { + /* Latch character */ + switch(typemap[i]) { + case UPPER: /* To UPPER */ + switch(curtable) { + case LOWER: /* ML UL */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + concat(binary_string, hexbit[29]); + if(debug) printf("UL "); + newtable = UPPER; + break; + case MIXED: /* UL */ + concat(binary_string, hexbit[29]); + if(debug) printf("UL "); + newtable = UPPER; + break; + case PUNC: /* UL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + newtable = UPPER; + break; + case DIGIT: /* UL */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + newtable = UPPER; + break; + } + break; + case LOWER: /* To LOWER */ + switch(curtable) { + case UPPER: /* LL */ + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case MIXED: /* LL */ + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case PUNC: /* UL LL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + case DIGIT: /* UL LL */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[28]); + if(debug) printf("LL "); + newtable = LOWER; + break; + } + break; + case MIXED: /* To MIXED */ + switch(curtable) { + case UPPER: /* ML */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case LOWER: /* ML */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case PUNC: /* UL ML */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + case DIGIT: /* UL ML */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + newtable = MIXED; + break; + } + break; + case PUNC: /* To PUNC */ + switch(curtable) { + case UPPER: /* ML PL */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + concat(binary_string, hexbit[30]); + if(debug) printf("PL "); + newtable = PUNC; + break; + case LOWER: /* ML PL */ + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + concat(binary_string, hexbit[30]); + if(debug) printf("PL "); + newtable = PUNC; + break; + case MIXED: /* PL */ + concat(binary_string, hexbit[30]); + if(debug) printf("PL "); + newtable = PUNC; + break; + case DIGIT: /* UL ML PL */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[29]); + if(debug) printf("ML "); + concat(binary_string, hexbit[30]); + if(debug) printf("PL "); + newtable = PUNC; + break; + } + break; + case DIGIT: /* To DIGIT */ + switch(curtable) { + case UPPER: /* DL */ + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case LOWER: /* DL */ + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case MIXED: /* UL DL */ + concat(binary_string, hexbit[29]); + if(debug) printf("UL "); + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + case PUNC: /* UL DL */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[30]); + if(debug) printf("DL "); + newtable = DIGIT; + break; + } + break; + case BINARY: /* To BINARY */ + lasttable = curtable; + switch(curtable) { + case UPPER: /* BS */ + concat(binary_string, hexbit[31]); + if(debug) printf("BS "); + newtable = BINARY; + break; + case LOWER: /* BS */ + concat(binary_string, hexbit[31]); + if(debug) printf("BS "); + newtable = BINARY; + break; + case MIXED: /* BS */ + concat(binary_string, hexbit[31]); + if(debug) printf("BS "); + newtable = BINARY; + break; + case PUNC: /* UL BS */ + concat(binary_string, hexbit[31]); + if(debug) printf("UL "); + concat(binary_string, hexbit[31]); + if(debug) printf("BS "); + newtable = BINARY; + break; + case DIGIT: /* UL BS */ + concat(binary_string, pentbit[14]); + if(debug) printf("UL "); + concat(binary_string, hexbit[31]); + if(debug) printf("BS "); + newtable = BINARY; + break; + } + + bytes = 0; + do{ + bytes++; + }while(typemap[i + (bytes - 1)] == BINARY); + bytes--; + + if(bytes > 2079) { + return ERROR_TOO_LONG; + } + + if(bytes > 31) { /* Put 00000 followed by 11-bit number of bytes less 31 */ + int adjusted; + + adjusted = bytes - 31; + concat(binary_string, "00000"); + if(adjusted & 0x400) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x200) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x100) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(adjusted & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + } else { /* Put 5-bit number of bytes */ + if(bytes & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(bytes & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(bytes & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(bytes & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(bytes & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + } + if(debug) printf("(%d bytes) ", bytes); + + break; + } + } + } + /* Add data to the binary string */ + curtable = newtable; + chartype = typemap[i]; + if(chartype > 64) { chartype -= 64; } + switch(chartype) { + case UPPER: + case LOWER: + case MIXED: + case PUNC: + if(charmap[i] >= 400) { + concat(binary_string, tribit[charmap[i] - 400]); + if(debug) printf("FLG(%d) ",charmap[i] - 400); + } else { + concat(binary_string, hexbit[charmap[i]]); + if(!((chartype == PUNC) && (charmap[i] == 0))) + if(debug) printf("%d ",charmap[i]); + } + break; + case DIGIT: + concat(binary_string, pentbit[charmap[i]]); + if(debug) printf("%d ",charmap[i]); + break; + case BINARY: + if(charmap[i] & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(charmap[i] & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(debug) printf("%d ",charmap[i]); + break; + } + + } + + if(debug) printf("\n"); + + if(strlen(binary_string) > 14970) { + return ERROR_TOO_LONG; + } + + return 0; +} + +int aztec(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int x, y, i, j, data_blocks, ecc_blocks, layers, total_bits; + char binary_string[20000], bit_pattern[20045], descriptor[42]; + char adjusted_string[20000]; + unsigned char desc_data[4], desc_ecc[6]; + int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length; + int remainder, padbits, count, gs1, adjustment_size; + int debug = 0, reader = 0; + int comp_loop = 4; + +#ifndef _MSC_VER + unsigned char local_source[length + 1]; +#else + unsigned char* local_source = (unsigned char*)_alloca(length + 1); +#endif + + memset(binary_string,0,20000); + memset(adjusted_string,0,20000); + + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + if(symbol->output_options & READER_INIT) { reader = 1; comp_loop = 1; } + if((gs1 == 1) && (reader == 1)) { + strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time"); + return ERROR_INVALID_OPTION; + } + + switch(symbol->input_mode) { + case DATA_MODE: + case GS1_MODE: + memcpy(local_source, source, length); + local_source[length] = '\0'; + break; + case UNICODE_MODE: + err_code = latin1_process(symbol, source, local_source, &length); + if(err_code != 0) { return err_code; } + break; + } + + /* Aztec code can't handle NULL characters */ + for(i = 0; i < length; i++) { + if(local_source[i] == '\0') { + strcpy(symbol->errtxt, "Invalid character (NULL) in input data"); + return ERROR_INVALID_DATA; + } + } + + err_code = aztec_text_process(local_source, length, binary_string, gs1); + + + if(err_code != 0) { + strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters"); + return err_code; + } + + if(!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) { + strcpy(symbol->errtxt, "Invalid error correction level - using default instead"); + err_code = WARN_INVALID_OPTION; + symbol->option_1 = -1; + } + + ecc_level = symbol->option_1; + + if((ecc_level == -1) || (ecc_level == 0)) { + ecc_level = 2; + } + + data_length = strlen(binary_string); + + layers = 0; /* Keep compiler happy! */ + data_maxsize = 0; /* Keep compiler happy! */ + adjustment_size = 0; + if(symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */ + do { + /* Decide what size symbol to use - the smallest that fits the data */ + compact = 0; /* 1 = Aztec Compact, 0 = Normal Aztec */ + layers = 0; + + switch(ecc_level) { + /* For each level of error correction work out the smallest symbol which + the data will fit in */ + case 1: for(i = 32; i > 0; i--) { + if((data_length + adjustment_size) < Aztec10DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec10DataSizes[i - 1]; + } + } + for(i = comp_loop; i > 0; i--) { + if((data_length + adjustment_size) < AztecCompact10DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact10DataSizes[i - 1]; + } + } + break; + case 2: for(i = 32; i > 0; i--) { + if((data_length + adjustment_size) < Aztec23DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec23DataSizes[i - 1]; + } + } + for(i = comp_loop; i > 0; i--) { + if((data_length + adjustment_size) < AztecCompact23DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact23DataSizes[i - 1]; + } + } + break; + case 3: for(i = 32; i > 0; i--) { + if((data_length + adjustment_size) < Aztec36DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec36DataSizes[i - 1]; + } + } + for(i = comp_loop; i > 0; i--) { + if((data_length + adjustment_size) < AztecCompact36DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact36DataSizes[i - 1]; + } + } + break; + case 4: for(i = 32; i > 0; i--) { + if((data_length + adjustment_size) < Aztec50DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec50DataSizes[i - 1]; + } + } + for(i = comp_loop; i > 0; i--) { + if((data_length + adjustment_size) < AztecCompact50DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact50DataSizes[i - 1]; + } + } + break; + } + + if(layers == 0) { /* Couldn't find a symbol which fits the data */ + strcpy(symbol->errtxt, "Input too long (too many bits for selected ECC)"); + return ERROR_TOO_LONG; + } + + /* Determine codeword bitlength - Table 3 */ + codeword_size = 6; /* if (layers <= 2) */ + if((layers >= 3) && (layers <= 8)) { codeword_size = 8; } + if((layers >= 9) && (layers <= 22)) { codeword_size = 10; } + if(layers >= 23) { codeword_size = 12; } + + j = 0; i = 0; + do { + if((j + 1) % codeword_size == 0) { + /* Last bit of codeword */ + int t, done = 0; + count = 0; + + /* Discover how many '1's in current codeword */ + for(t = 0; t < (codeword_size - 1); t++) { + if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++; + } + + if(count == (codeword_size - 1)) { + adjusted_string[j] = '0'; + j++; + done = 1; + } + + if(count == 0) { + adjusted_string[j] = '1'; + j++; + done = 1; + } + + if(done == 0) { + adjusted_string[j] = binary_string[i]; + j++; + i++; + } + } + adjusted_string[j] = binary_string[i]; + j++; + i++; + } while (i <= (data_length + 1)); + adjusted_string[j] = '\0'; + adjusted_length = strlen(adjusted_string); + adjustment_size = adjusted_length - data_length; + + /* Add padding */ + remainder = adjusted_length % codeword_size; + + padbits = codeword_size - remainder; + if(padbits == codeword_size) { padbits = 0; } + + for(i = 0; i < padbits; i++) { + concat(adjusted_string, "1"); + } + adjusted_length = strlen(adjusted_string); + + count = 0; + for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) { + if(adjusted_string[i] == '1') { count++; } + } + if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; } + + if(debug) { + printf("Codewords:\n"); + for(i = 0; i < (adjusted_length / codeword_size); i++) { + for(j = 0; j < codeword_size; j++) { + printf("%c", adjusted_string[(i * codeword_size) + j]); + } + printf("\n"); + } + } + + } while(adjusted_length > data_maxsize); + /* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s + means that the binary string has had to be lengthened beyond the maximum number of bits that can + be encoded in a symbol of the selected size */ + + } else { /* The size of the symbol has been specified by the user */ + if((reader == 1) && ((symbol->option_2 >= 2) && (symbol->option_2 <= 4))) { + symbol->option_2 = 5; + } + if((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { + compact = 1; + layers = symbol->option_2; + } + if((symbol->option_2 >= 5) && (symbol->option_2 <= 36)) { + compact = 0; + layers = symbol->option_2 - 4; + } + if((symbol->option_2 < 0) || (symbol->option_2 > 36)) { + strcpy(symbol->errtxt, "Invalid Aztec Code size"); + return ERROR_INVALID_OPTION; + } + + /* Determine codeword bitlength - Table 3 */ + if((layers >= 0) && (layers <= 2)) { codeword_size = 6; } + if((layers >= 3) && (layers <= 8)) { codeword_size = 8; } + if((layers >= 9) && (layers <= 22)) { codeword_size = 10; } + if(layers >= 23) { codeword_size = 12; } + + j = 0; i = 0; + do { + if((j + 1) % codeword_size == 0) { + /* Last bit of codeword */ + int t, done = 0; + count = 0; + + /* Discover how many '1's in current codeword */ + for(t = 0; t < (codeword_size - 1); t++) { + if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++; + } + + if(count == (codeword_size - 1)) { + adjusted_string[j] = '0'; + j++; + done = 1; + } + + if(count == 0) { + adjusted_string[j] = '1'; + j++; + done = 1; + } + + if(done == 0) { + adjusted_string[j] = binary_string[i]; + j++; + i++; + } + } + adjusted_string[j] = binary_string[i]; + j++; + i++; + } while (i <= (data_length + 1)); + adjusted_string[j] = '\0'; + adjusted_length = strlen(adjusted_string); + + remainder = adjusted_length % codeword_size; + + padbits = codeword_size - remainder; + if(padbits == codeword_size) { padbits = 0; } + + for(i = 0; i < padbits; i++) { + concat(adjusted_string, "1"); + } + adjusted_length = strlen(adjusted_string); + + count = 0; + for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) { + if(adjusted_string[i] == '1') { count++; } + } + if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; } + + /* Check if the data actually fits into the selected symbol size */ + if (compact) { + data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3); + } else { + data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3); + } + + if(adjusted_length > data_maxsize) { + strcpy(symbol->errtxt, "Data too long for specified Aztec Code symbol size"); + return ERROR_TOO_LONG; + } + + if(debug) { + printf("Codewords:\n"); + for(i = 0; i < (adjusted_length / codeword_size); i++) { + for(j = 0; j < codeword_size; j++) { + printf("%c", adjusted_string[(i * codeword_size) + j]); + } + printf("\n"); + } + } + + } + + if(reader && (layers > 22)) { + strcpy(symbol->errtxt, "Data too long for reader initialisation symbol"); + return ERROR_TOO_LONG; + } + + data_blocks = adjusted_length / codeword_size; + + if(compact) { + ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks; + } else { + ecc_blocks = AztecSizes[layers - 1] - data_blocks; + } + + if(debug) { + printf("Generating a "); + if(compact) { printf("compact"); } else { printf("full-size"); } + printf(" symbol with %d layers\n", layers); + printf("Requires "); + if(compact) { printf("%d", AztecCompactSizes[layers - 1]); } else { printf("%d", AztecSizes[layers - 1]); } + printf(" codewords of %d-bits\n", codeword_size); + printf(" (%d data words, %d ecc words)\n", data_blocks, ecc_blocks); + } + +#ifndef _MSC_VER + unsigned int data_part[data_blocks + 3], ecc_part[ecc_blocks + 3]; +#else + unsigned int* data_part = (unsigned int*)_alloca((data_blocks + 3) * sizeof(unsigned int)); + unsigned int* ecc_part = (unsigned int*)_alloca((ecc_blocks + 3) * sizeof(unsigned int)); +#endif + /* Copy across data into separate integers */ + memset(data_part,0,(data_blocks + 2)*sizeof(int)); + memset(ecc_part,0,(ecc_blocks + 2)*sizeof(int)); + + /* Split into codewords and calculate reed-colomon error correction codes */ + switch(codeword_size) { + case 6: + for(i = 0; i < data_blocks; i++) { + if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 32; } + if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 16; } + if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 8; } + if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 4; } + if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 2; } + if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 1; } + } + rs_init_gf(0x43); + rs_init_code(ecc_blocks, 1); + rs_encode_long(data_blocks, data_part, ecc_part); + for(i = (ecc_blocks - 1); i >= 0; i--) { + if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + } + rs_free(); + break; + case 8: + for(i = 0; i < data_blocks; i++) { + if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 128; } + if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 64; } + if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 32; } + if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 16; } + if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 8; } + if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 4; } + if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 2; } + if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 1; } + } + rs_init_gf(0x12d); + rs_init_code(ecc_blocks, 1); + rs_encode_long(data_blocks, data_part, ecc_part); + for(i = (ecc_blocks - 1); i >= 0; i--) { + if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + } + rs_free(); + break; + case 10: + for(i = 0; i < data_blocks; i++) { + if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 512; } + if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 256; } + if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 128; } + if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 64; } + if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 32; } + if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 16; } + if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 8; } + if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 4; } + if(adjusted_string[(i * codeword_size) + 8] == '1') { data_part[i] += 2; } + if(adjusted_string[(i * codeword_size) + 9] == '1') { data_part[i] += 1; } + } + rs_init_gf(0x409); + rs_init_code(ecc_blocks, 1); + rs_encode_long(data_blocks, data_part, ecc_part); + for(i = (ecc_blocks - 1); i >= 0; i--) { + if(ecc_part[i] & 0x200) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x100) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + } + rs_free(); + break; + case 12: + for(i = 0; i < data_blocks; i++) { + if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 2048; } + if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 1024; } + if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 512; } + if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 256; } + if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 128; } + if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 64; } + if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 32; } + if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 16; } + if(adjusted_string[(i * codeword_size) + 8] == '1') { data_part[i] += 8; } + if(adjusted_string[(i * codeword_size) + 9] == '1') { data_part[i] += 4; } + if(adjusted_string[(i * codeword_size) + 10] == '1') { data_part[i] += 2; } + if(adjusted_string[(i * codeword_size) + 11] == '1') { data_part[i] += 1; } + } + rs_init_gf(0x1069); + rs_init_code(ecc_blocks, 1); + rs_encode_long(data_blocks, data_part, ecc_part); + for(i = (ecc_blocks - 1); i >= 0; i--) { + if(ecc_part[i] & 0x800) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x400) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x200) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x100) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } + } + rs_free(); + break; + } + + /* Invert the data so that actual data is on the outside and reed-solomon on the inside */ + memset(bit_pattern,'0',20045); + + total_bits = (data_blocks + ecc_blocks) * codeword_size; + for(i = 0; i < total_bits; i++) { + bit_pattern[i] = adjusted_string[total_bits - i - 1]; + } + + /* Now add the symbol descriptor */ + memset(desc_data,0,4); + memset(desc_ecc,0,6); + memset(descriptor,0,42); + + if(compact) { + /* The first 2 bits represent the number of layers minus 1 */ + if((layers - 1) & 0x02) { descriptor[0] = '1'; } else { descriptor[0] = '0'; } + if((layers - 1) & 0x01) { descriptor[1] = '1'; } else { descriptor[1] = '0'; } + /* The next 6 bits represent the number of data blocks minus 1 */ + if(reader) { + descriptor[2] = '1'; + } else { + if((data_blocks - 1) & 0x20) { descriptor[2] = '1'; } else { descriptor[2] = '0'; } + } + if((data_blocks - 1) & 0x10) { descriptor[3] = '1'; } else { descriptor[3] = '0'; } + if((data_blocks - 1) & 0x08) { descriptor[4] = '1'; } else { descriptor[4] = '0'; } + if((data_blocks - 1) & 0x04) { descriptor[5] = '1'; } else { descriptor[5] = '0'; } + if((data_blocks - 1) & 0x02) { descriptor[6] = '1'; } else { descriptor[6] = '0'; } + if((data_blocks - 1) & 0x01) { descriptor[7] = '1'; } else { descriptor[7] = '0'; } + descriptor[8] = '\0'; + if(debug) printf("Mode Message = %s\n", descriptor); + } else { + /* The first 5 bits represent the number of layers minus 1 */ + if((layers - 1) & 0x10) { descriptor[0] = '1'; } else { descriptor[0] = '0'; } + if((layers - 1) & 0x08) { descriptor[1] = '1'; } else { descriptor[1] = '0'; } + if((layers - 1) & 0x04) { descriptor[2] = '1'; } else { descriptor[2] = '0'; } + if((layers - 1) & 0x02) { descriptor[3] = '1'; } else { descriptor[3] = '0'; } + if((layers - 1) & 0x01) { descriptor[4] = '1'; } else { descriptor[4] = '0'; } + /* The next 11 bits represent the number of data blocks minus 1 */ + if(reader) { + descriptor[5] = '1'; + } else { + if((data_blocks - 1) & 0x400) { descriptor[5] = '1'; } else { descriptor[5] = '0'; } + } + if((data_blocks - 1) & 0x200) { descriptor[6] = '1'; } else { descriptor[6] = '0'; } + if((data_blocks - 1) & 0x100) { descriptor[7] = '1'; } else { descriptor[7] = '0'; } + if((data_blocks - 1) & 0x80) { descriptor[8] = '1'; } else { descriptor[8] = '0'; } + if((data_blocks - 1) & 0x40) { descriptor[9] = '1'; } else { descriptor[9] = '0'; } + if((data_blocks - 1) & 0x20) { descriptor[10] = '1'; } else { descriptor[10] = '0'; } + if((data_blocks - 1) & 0x10) { descriptor[11] = '1'; } else { descriptor[11] = '0'; } + if((data_blocks - 1) & 0x08) { descriptor[12] = '1'; } else { descriptor[12] = '0'; } + if((data_blocks - 1) & 0x04) { descriptor[13] = '1'; } else { descriptor[13] = '0'; } + if((data_blocks - 1) & 0x02) { descriptor[14] = '1'; } else { descriptor[14] = '0'; } + if((data_blocks - 1) & 0x01) { descriptor[15] = '1'; } else { descriptor[15] = '0'; } + descriptor[16] = '\0'; + if(debug) printf("Mode Message = %s\n", descriptor); + } + + /* Split into 4-bit codewords */ + for(i = 0; i < 4; i++) { + if(descriptor[i * 4] == '1') { desc_data[i] += 8; } + if(descriptor[(i * 4) + 1] == '1') { desc_data[i] += 4; } + if(descriptor[(i * 4) + 2] == '1') { desc_data[i] += 2; } + if(descriptor[(i * 4) + 3] == '1') { desc_data[i] += 1; } + } + + /* Add reed-solomon error correction with Galois field GF(16) and prime modulus + x^4 + x + 1 (section 7.2.3)*/ + + rs_init_gf(0x13); + if(compact) { + rs_init_code(5, 1); + rs_encode(2, desc_data, desc_ecc); + for(i = 0; i < 5; i++) { + if(desc_ecc[4 - i] & 0x08) { descriptor[(i * 4) + 8] = '1'; } else { descriptor[(i * 4) + 8] = '0'; } + if(desc_ecc[4 - i] & 0x04) { descriptor[(i * 4) + 9] = '1'; } else { descriptor[(i * 4) + 9] = '0'; } + if(desc_ecc[4 - i] & 0x02) { descriptor[(i * 4) + 10] = '1'; } else { descriptor[(i * 4) + 10] = '0'; } + if(desc_ecc[4 - i] & 0x01) { descriptor[(i * 4) + 11] = '1'; } else { descriptor[(i * 4) + 11] = '0'; } + } + } else { + rs_init_code(6, 1); + rs_encode(4, desc_data, desc_ecc); + for(i = 0; i < 6; i++) { + if(desc_ecc[5 - i] & 0x08) { descriptor[(i * 4) + 16] = '1'; } else { descriptor[(i * 4) + 16] = '0'; } + if(desc_ecc[5 - i] & 0x04) { descriptor[(i * 4) + 17] = '1'; } else { descriptor[(i * 4) + 17] = '0'; } + if(desc_ecc[5 - i] & 0x02) { descriptor[(i * 4) + 18] = '1'; } else { descriptor[(i * 4) + 18] = '0'; } + if(desc_ecc[5 - i] & 0x01) { descriptor[(i * 4) + 19] = '1'; } else { descriptor[(i * 4) + 19] = '0'; } + } + } + rs_free(); + + /* Merge descriptor with the rest of the symbol */ + for(i = 0; i < 40; i++) { + if(compact) { + bit_pattern[2000 + i - 2] = descriptor[i]; + } else { + bit_pattern[20000 + i - 2] = descriptor[i]; + } + } + + /* Plot all of the data into the symbol in pre-defined spiral pattern */ + if(compact) { + + for(y = AztecCompactOffset[layers - 1]; y < (27 - AztecCompactOffset[layers - 1]); y++) { + for(x = AztecCompactOffset[layers - 1]; x < (27 - AztecCompactOffset[layers - 1]); x++) { + if(CompactAztecMap[(y * 27) + x] == 1) { + set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); + } + if(CompactAztecMap[(y * 27) + x] >= 2) { + if(bit_pattern[CompactAztecMap[(y * 27) + x] - 2] == '1') { + set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); + } + } + } + symbol->row_height[y - AztecCompactOffset[layers - 1]] = 1; + } + symbol->rows = 27 - (2 * AztecCompactOffset[layers - 1]); + symbol->width = 27 - (2 * AztecCompactOffset[layers - 1]); + } else { + + for(y = AztecOffset[layers - 1]; y < (151 - AztecOffset[layers - 1]); y++) { + for(x = AztecOffset[layers - 1]; x < (151 - AztecOffset[layers - 1]); x++) { + if(AztecMap[(y * 151) + x] == 1) { + set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); + } + if(AztecMap[(y * 151) + x] >= 2) { + if(bit_pattern[AztecMap[(y * 151) + x] - 2] == '1') { + set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); + } + } + } + symbol->row_height[y - AztecOffset[layers - 1]] = 1; + } + symbol->rows = 151 - (2 * AztecOffset[layers - 1]); + symbol->width = 151 - (2 * AztecOffset[layers - 1]); + } + + return err_code; +} + +int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int input_value, error_number, i, y, x; + char binary_string[28]; + unsigned char data_codewords[3], ecc_codewords[6]; + + error_number = 0; + input_value = 0; + if(length > 3) { + strcpy(symbol->errtxt, "Input too large"); + return ERROR_INVALID_DATA; + } + error_number = is_sane(NEON, source, length); + if(error_number != 0) { + strcpy(symbol->errtxt, "Invalid characters in input"); + return ERROR_INVALID_DATA; + } + switch(length) { + case 3: input_value = 100 * ctoi(source[0]); + input_value += 10 * ctoi(source[1]); + input_value += ctoi(source[2]); + break; + case 2: input_value = 10 * ctoi(source[0]); + input_value += ctoi(source[1]); + break; + case 1: input_value = ctoi(source[0]); + break; + } + + if(input_value > 255) { + strcpy(symbol->errtxt, "Input too large"); + return ERROR_INVALID_DATA; + } + + strcpy(binary_string, ""); + if(input_value & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + if(input_value & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } + + data_codewords[0] = 0; + data_codewords[1] = 0; + + for(i = 0; i < 2; i++) { + if(binary_string[i * 4] == '1') { data_codewords[i] += 8; } + if(binary_string[(i * 4) + 1] == '1') { data_codewords[i] += 4; } + if(binary_string[(i * 4) + 2] == '1') { data_codewords[i] += 2; } + if(binary_string[(i * 4) + 3] == '1') { data_codewords[i] += 1; } + } + + rs_init_gf(0x13); + rs_init_code(5, 1); + rs_encode(2, data_codewords, ecc_codewords); + rs_free(); + + strcpy(binary_string, ""); + + for(i = 0; i < 5; i++) { + if(ecc_codewords[4 - i] & 0x08) { binary_string[(i * 4) + 8] = '1'; } else { binary_string[(i * 4) + 8] = '0'; } + if(ecc_codewords[4 - i] & 0x04) { binary_string[(i * 4) + 9] = '1'; } else { binary_string[(i * 4) + 9] = '0'; } + if(ecc_codewords[4 - i] & 0x02) { binary_string[(i * 4) + 10] = '1'; } else { binary_string[(i * 4) + 10] = '0'; } + if(ecc_codewords[4 - i] & 0x01) { binary_string[(i * 4) + 11] = '1'; } else { binary_string[(i * 4) + 11] = '0'; } + } + + for(i = 0; i < 28; i += 2) { + if(binary_string[i] == '1') { binary_string[i] = '0'; } else { binary_string[i] = '1'; } + } + + for(y = 8; y < 19; y++) { + for(x = 8; x < 19; x++) { + if(CompactAztecMap[(y * 27) + x] == 1) { + set_module(symbol, y - 8, x - 8); + } + if(CompactAztecMap[(y * 27) + x] >= 2) { + if(binary_string[CompactAztecMap[(y * 27) + x] - 2000] == '1') { + set_module(symbol, y - 8, x - 8); + } + } + } + symbol->row_height[y - 8] = 1; + } + symbol->rows = 11; + symbol->width = 11; + + return 0; +} \ No newline at end of file diff --git a/backend/aztec.h b/backend/aztec.h new file mode 100644 index 00000000..93e0e278 --- /dev/null +++ b/backend/aztec.h @@ -0,0 +1,291 @@ +/* aztec.c - Handles Aztec Mesa 2D Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +#define UPPER 1 +#define LOWER 2 +#define MIXED 4 +#define PUNC 8 +#define DIGIT 16 +#define BINARY 32 + +static int AztecMap[] = { /* 151 x 151 data grid */ + 19969,19968,18851,18853,18855,18857,18859,18861,18863,18865,18867,0,18869,18871,18873,18875,18877,18879,18881,18883,18885,18887,18889,18891,18893,18895,18897,0,18899,18901,18903,18905,18907,18909,18911,18913,18915,18917,18919,18921,18923,18925,18927,0,18929,18931,18933,18935,18937,18939,18941,18943,18945,18947,18949,18951,18953,18955,18957,0,18959,18961,18963,18965,18967,18969,18971,18973,18975,18977,18979,18981,18983,18985,18987,0,18989,18991,18993,18995,18997,18999,19001,19003,19005,19007,19009,19011,19013,19015,19017,0,19019,19021,19023,19025,19027,19029,19031,19033,19035,19037,19039,19041,19043,19045,19047,0,19049,19051,19053,19055,19057,19059,19061,19063,19065,19067,19069,19071,19073,19075,19077,0,19079,19081,19083,19085,19087,19089,19091,19093,19095,19097,19099,19101,19103,19105,19107,0,19109,19111,19113,19115,19117,19119,19121,19123,19125,19127,19129, + 19967,19966,18850,18852,18854,18856,18858,18860,18862,18864,18866,1,18868,18870,18872,18874,18876,18878,18880,18882,18884,18886,18888,18890,18892,18894,18896,1,18898,18900,18902,18904,18906,18908,18910,18912,18914,18916,18918,18920,18922,18924,18926,1,18928,18930,18932,18934,18936,18938,18940,18942,18944,18946,18948,18950,18952,18954,18956,1,18958,18960,18962,18964,18966,18968,18970,18972,18974,18976,18978,18980,18982,18984,18986,1,18988,18990,18992,18994,18996,18998,19000,19002,19004,19006,19008,19010,19012,19014,19016,1,19018,19020,19022,19024,19026,19028,19030,19032,19034,19036,19038,19040,19042,19044,19046,1,19048,19050,19052,19054,19056,19058,19060,19062,19064,19066,19068,19070,19072,19074,19076,1,19078,19080,19082,19084,19086,19088,19090,19092,19094,19096,19098,19100,19102,19104,19106,1,19108,19110,19112,19114,19116,19118,19120,19122,19124,19126,19128, + 19965,19964,18849,18848,17763,17765,17767,17769,17771,17773,17775,0,17777,17779,17781,17783,17785,17787,17789,17791,17793,17795,17797,17799,17801,17803,17805,0,17807,17809,17811,17813,17815,17817,17819,17821,17823,17825,17827,17829,17831,17833,17835,0,17837,17839,17841,17843,17845,17847,17849,17851,17853,17855,17857,17859,17861,17863,17865,0,17867,17869,17871,17873,17875,17877,17879,17881,17883,17885,17887,17889,17891,17893,17895,0,17897,17899,17901,17903,17905,17907,17909,17911,17913,17915,17917,17919,17921,17923,17925,0,17927,17929,17931,17933,17935,17937,17939,17941,17943,17945,17947,17949,17951,17953,17955,0,17957,17959,17961,17963,17965,17967,17969,17971,17973,17975,17977,17979,17981,17983,17985,0,17987,17989,17991,17993,17995,17997,17999,18001,18003,18005,18007,18009,18011,18013,18015,0,18017,18019,18021,18023,18025,18027,18029,18031,18033,19130,19131, + 19963,19962,18847,18846,17762,17764,17766,17768,17770,17772,17774,1,17776,17778,17780,17782,17784,17786,17788,17790,17792,17794,17796,17798,17800,17802,17804,1,17806,17808,17810,17812,17814,17816,17818,17820,17822,17824,17826,17828,17830,17832,17834,1,17836,17838,17840,17842,17844,17846,17848,17850,17852,17854,17856,17858,17860,17862,17864,1,17866,17868,17870,17872,17874,17876,17878,17880,17882,17884,17886,17888,17890,17892,17894,1,17896,17898,17900,17902,17904,17906,17908,17910,17912,17914,17916,17918,17920,17922,17924,1,17926,17928,17930,17932,17934,17936,17938,17940,17942,17944,17946,17948,17950,17952,17954,1,17956,17958,17960,17962,17964,17966,17968,17970,17972,17974,17976,17978,17980,17982,17984,1,17986,17988,17990,17992,17994,17996,17998,18000,18002,18004,18006,18008,18010,18012,18014,1,18016,18018,18020,18022,18024,18026,18028,18030,18032,19132,19133, + 19961,19960,18845,18844,17761,17760,16707,16709,16711,16713,16715,0,16717,16719,16721,16723,16725,16727,16729,16731,16733,16735,16737,16739,16741,16743,16745,0,16747,16749,16751,16753,16755,16757,16759,16761,16763,16765,16767,16769,16771,16773,16775,0,16777,16779,16781,16783,16785,16787,16789,16791,16793,16795,16797,16799,16801,16803,16805,0,16807,16809,16811,16813,16815,16817,16819,16821,16823,16825,16827,16829,16831,16833,16835,0,16837,16839,16841,16843,16845,16847,16849,16851,16853,16855,16857,16859,16861,16863,16865,0,16867,16869,16871,16873,16875,16877,16879,16881,16883,16885,16887,16889,16891,16893,16895,0,16897,16899,16901,16903,16905,16907,16909,16911,16913,16915,16917,16919,16921,16923,16925,0,16927,16929,16931,16933,16935,16937,16939,16941,16943,16945,16947,16949,16951,16953,16955,0,16957,16959,16961,16963,16965,16967,16969,18034,18035,19134,19135, + 19959,19958,18843,18842,17759,17758,16706,16708,16710,16712,16714,1,16716,16718,16720,16722,16724,16726,16728,16730,16732,16734,16736,16738,16740,16742,16744,1,16746,16748,16750,16752,16754,16756,16758,16760,16762,16764,16766,16768,16770,16772,16774,1,16776,16778,16780,16782,16784,16786,16788,16790,16792,16794,16796,16798,16800,16802,16804,1,16806,16808,16810,16812,16814,16816,16818,16820,16822,16824,16826,16828,16830,16832,16834,1,16836,16838,16840,16842,16844,16846,16848,16850,16852,16854,16856,16858,16860,16862,16864,1,16866,16868,16870,16872,16874,16876,16878,16880,16882,16884,16886,16888,16890,16892,16894,1,16896,16898,16900,16902,16904,16906,16908,16910,16912,16914,16916,16918,16920,16922,16924,1,16926,16928,16930,16932,16934,16936,16938,16940,16942,16944,16946,16948,16950,16952,16954,1,16956,16958,16960,16962,16964,16966,16968,18036,18037,19136,19137, + 19957,19956,18841,18840,17757,17756,16705,16704,15683,15685,15687,0,15689,15691,15693,15695,15697,15699,15701,15703,15705,15707,15709,15711,15713,15715,15717,0,15719,15721,15723,15725,15727,15729,15731,15733,15735,15737,15739,15741,15743,15745,15747,0,15749,15751,15753,15755,15757,15759,15761,15763,15765,15767,15769,15771,15773,15775,15777,0,15779,15781,15783,15785,15787,15789,15791,15793,15795,15797,15799,15801,15803,15805,15807,0,15809,15811,15813,15815,15817,15819,15821,15823,15825,15827,15829,15831,15833,15835,15837,0,15839,15841,15843,15845,15847,15849,15851,15853,15855,15857,15859,15861,15863,15865,15867,0,15869,15871,15873,15875,15877,15879,15881,15883,15885,15887,15889,15891,15893,15895,15897,0,15899,15901,15903,15905,15907,15909,15911,15913,15915,15917,15919,15921,15923,15925,15927,0,15929,15931,15933,15935,15937,16970,16971,18038,18039,19138,19139, + 19955,19954,18839,18838,17755,17754,16703,16702,15682,15684,15686,1,15688,15690,15692,15694,15696,15698,15700,15702,15704,15706,15708,15710,15712,15714,15716,1,15718,15720,15722,15724,15726,15728,15730,15732,15734,15736,15738,15740,15742,15744,15746,1,15748,15750,15752,15754,15756,15758,15760,15762,15764,15766,15768,15770,15772,15774,15776,1,15778,15780,15782,15784,15786,15788,15790,15792,15794,15796,15798,15800,15802,15804,15806,1,15808,15810,15812,15814,15816,15818,15820,15822,15824,15826,15828,15830,15832,15834,15836,1,15838,15840,15842,15844,15846,15848,15850,15852,15854,15856,15858,15860,15862,15864,15866,1,15868,15870,15872,15874,15876,15878,15880,15882,15884,15886,15888,15890,15892,15894,15896,1,15898,15900,15902,15904,15906,15908,15910,15912,15914,15916,15918,15920,15922,15924,15926,1,15928,15930,15932,15934,15936,16972,16973,18040,18041,19140,19141, + 19953,19952,18837,18836,17753,17752,16701,16700,15681,15680,14691,0,14693,14695,14697,14699,14701,14703,14705,14707,14709,14711,14713,14715,14717,14719,14721,0,14723,14725,14727,14729,14731,14733,14735,14737,14739,14741,14743,14745,14747,14749,14751,0,14753,14755,14757,14759,14761,14763,14765,14767,14769,14771,14773,14775,14777,14779,14781,0,14783,14785,14787,14789,14791,14793,14795,14797,14799,14801,14803,14805,14807,14809,14811,0,14813,14815,14817,14819,14821,14823,14825,14827,14829,14831,14833,14835,14837,14839,14841,0,14843,14845,14847,14849,14851,14853,14855,14857,14859,14861,14863,14865,14867,14869,14871,0,14873,14875,14877,14879,14881,14883,14885,14887,14889,14891,14893,14895,14897,14899,14901,0,14903,14905,14907,14909,14911,14913,14915,14917,14919,14921,14923,14925,14927,14929,14931,0,14933,14935,14937,15938,15939,16974,16975,18042,18043,19142,19143, + 19951,19950,18835,18834,17751,17750,16699,16698,15679,15678,14690,1,14692,14694,14696,14698,14700,14702,14704,14706,14708,14710,14712,14714,14716,14718,14720,1,14722,14724,14726,14728,14730,14732,14734,14736,14738,14740,14742,14744,14746,14748,14750,1,14752,14754,14756,14758,14760,14762,14764,14766,14768,14770,14772,14774,14776,14778,14780,1,14782,14784,14786,14788,14790,14792,14794,14796,14798,14800,14802,14804,14806,14808,14810,1,14812,14814,14816,14818,14820,14822,14824,14826,14828,14830,14832,14834,14836,14838,14840,1,14842,14844,14846,14848,14850,14852,14854,14856,14858,14860,14862,14864,14866,14868,14870,1,14872,14874,14876,14878,14880,14882,14884,14886,14888,14890,14892,14894,14896,14898,14900,1,14902,14904,14906,14908,14910,14912,14914,14916,14918,14920,14922,14924,14926,14928,14930,1,14932,14934,14936,15940,15941,16976,16977,18044,18045,19144,19145, + 19949,19948,18833,18832,17749,17748,16697,16696,15677,15676,14689,0,14688,13731,13733,13735,13737,13739,13741,13743,13745,13747,13749,13751,13753,13755,13757,0,13759,13761,13763,13765,13767,13769,13771,13773,13775,13777,13779,13781,13783,13785,13787,0,13789,13791,13793,13795,13797,13799,13801,13803,13805,13807,13809,13811,13813,13815,13817,0,13819,13821,13823,13825,13827,13829,13831,13833,13835,13837,13839,13841,13843,13845,13847,0,13849,13851,13853,13855,13857,13859,13861,13863,13865,13867,13869,13871,13873,13875,13877,0,13879,13881,13883,13885,13887,13889,13891,13893,13895,13897,13899,13901,13903,13905,13907,0,13909,13911,13913,13915,13917,13919,13921,13923,13925,13927,13929,13931,13933,13935,13937,0,13939,13941,13943,13945,13947,13949,13951,13953,13955,13957,13959,13961,13963,13965,13967,0,13969,14938,14939,15942,15943,16978,16979,18046,18047,19146,19147, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19947,19946,18831,18830,17747,17746,16695,16694,15675,15674,14687,0,14686,13730,13732,13734,13736,13738,13740,13742,13744,13746,13748,13750,13752,13754,13756,0,13758,13760,13762,13764,13766,13768,13770,13772,13774,13776,13778,13780,13782,13784,13786,0,13788,13790,13792,13794,13796,13798,13800,13802,13804,13806,13808,13810,13812,13814,13816,0,13818,13820,13822,13824,13826,13828,13830,13832,13834,13836,13838,13840,13842,13844,13846,0,13848,13850,13852,13854,13856,13858,13860,13862,13864,13866,13868,13870,13872,13874,13876,0,13878,13880,13882,13884,13886,13888,13890,13892,13894,13896,13898,13900,13902,13904,13906,0,13908,13910,13912,13914,13916,13918,13920,13922,13924,13926,13928,13930,13932,13934,13936,0,13938,13940,13942,13944,13946,13948,13950,13952,13954,13956,13958,13960,13962,13964,13966,0,13968,14940,14941,15944,15945,16980,16981,18048,18049,19148,19149, + 19945,19944,18829,18828,17745,17744,16693,16692,15673,15672,14685,1,14684,13729,13728,12803,12805,12807,12809,12811,12813,12815,12817,12819,12821,12823,12825,1,12827,12829,12831,12833,12835,12837,12839,12841,12843,12845,12847,12849,12851,12853,12855,1,12857,12859,12861,12863,12865,12867,12869,12871,12873,12875,12877,12879,12881,12883,12885,1,12887,12889,12891,12893,12895,12897,12899,12901,12903,12905,12907,12909,12911,12913,12915,1,12917,12919,12921,12923,12925,12927,12929,12931,12933,12935,12937,12939,12941,12943,12945,1,12947,12949,12951,12953,12955,12957,12959,12961,12963,12965,12967,12969,12971,12973,12975,1,12977,12979,12981,12983,12985,12987,12989,12991,12993,12995,12997,12999,13001,13003,13005,1,13007,13009,13011,13013,13015,13017,13019,13021,13023,13025,13027,13029,13031,13033,13970,1,13971,14942,14943,15946,15947,16982,16983,18050,18051,19150,19151, + 19943,19942,18827,18826,17743,17742,16691,16690,15671,15670,14683,0,14682,13727,13726,12802,12804,12806,12808,12810,12812,12814,12816,12818,12820,12822,12824,0,12826,12828,12830,12832,12834,12836,12838,12840,12842,12844,12846,12848,12850,12852,12854,0,12856,12858,12860,12862,12864,12866,12868,12870,12872,12874,12876,12878,12880,12882,12884,0,12886,12888,12890,12892,12894,12896,12898,12900,12902,12904,12906,12908,12910,12912,12914,0,12916,12918,12920,12922,12924,12926,12928,12930,12932,12934,12936,12938,12940,12942,12944,0,12946,12948,12950,12952,12954,12956,12958,12960,12962,12964,12966,12968,12970,12972,12974,0,12976,12978,12980,12982,12984,12986,12988,12990,12992,12994,12996,12998,13000,13002,13004,0,13006,13008,13010,13012,13014,13016,13018,13020,13022,13024,13026,13028,13030,13032,13972,0,13973,14944,14945,15948,15949,16984,16985,18052,18053,19152,19153, + 19941,19940,18825,18824,17741,17740,16689,16688,15669,15668,14681,1,14680,13725,13724,12801,12800,11907,11909,11911,11913,11915,11917,11919,11921,11923,11925,1,11927,11929,11931,11933,11935,11937,11939,11941,11943,11945,11947,11949,11951,11953,11955,1,11957,11959,11961,11963,11965,11967,11969,11971,11973,11975,11977,11979,11981,11983,11985,1,11987,11989,11991,11993,11995,11997,11999,12001,12003,12005,12007,12009,12011,12013,12015,1,12017,12019,12021,12023,12025,12027,12029,12031,12033,12035,12037,12039,12041,12043,12045,1,12047,12049,12051,12053,12055,12057,12059,12061,12063,12065,12067,12069,12071,12073,12075,1,12077,12079,12081,12083,12085,12087,12089,12091,12093,12095,12097,12099,12101,12103,12105,1,12107,12109,12111,12113,12115,12117,12119,12121,12123,12125,12127,12129,13034,13035,13974,1,13975,14946,14947,15950,15951,16986,16987,18054,18055,19154,19155, + 19939,19938,18823,18822,17739,17738,16687,16686,15667,15666,14679,0,14678,13723,13722,12799,12798,11906,11908,11910,11912,11914,11916,11918,11920,11922,11924,0,11926,11928,11930,11932,11934,11936,11938,11940,11942,11944,11946,11948,11950,11952,11954,0,11956,11958,11960,11962,11964,11966,11968,11970,11972,11974,11976,11978,11980,11982,11984,0,11986,11988,11990,11992,11994,11996,11998,12000,12002,12004,12006,12008,12010,12012,12014,0,12016,12018,12020,12022,12024,12026,12028,12030,12032,12034,12036,12038,12040,12042,12044,0,12046,12048,12050,12052,12054,12056,12058,12060,12062,12064,12066,12068,12070,12072,12074,0,12076,12078,12080,12082,12084,12086,12088,12090,12092,12094,12096,12098,12100,12102,12104,0,12106,12108,12110,12112,12114,12116,12118,12120,12122,12124,12126,12128,13036,13037,13976,0,13977,14948,14949,15952,15953,16988,16989,18056,18057,19156,19157, + 19937,19936,18821,18820,17737,17736,16685,16684,15665,15664,14677,1,14676,13721,13720,12797,12796,11905,11904,11043,11045,11047,11049,11051,11053,11055,11057,1,11059,11061,11063,11065,11067,11069,11071,11073,11075,11077,11079,11081,11083,11085,11087,1,11089,11091,11093,11095,11097,11099,11101,11103,11105,11107,11109,11111,11113,11115,11117,1,11119,11121,11123,11125,11127,11129,11131,11133,11135,11137,11139,11141,11143,11145,11147,1,11149,11151,11153,11155,11157,11159,11161,11163,11165,11167,11169,11171,11173,11175,11177,1,11179,11181,11183,11185,11187,11189,11191,11193,11195,11197,11199,11201,11203,11205,11207,1,11209,11211,11213,11215,11217,11219,11221,11223,11225,11227,11229,11231,11233,11235,11237,1,11239,11241,11243,11245,11247,11249,11251,11253,11255,11257,12130,12131,13038,13039,13978,1,13979,14950,14951,15954,15955,16990,16991,18058,18059,19158,19159, + 19935,19934,18819,18818,17735,17734,16683,16682,15663,15662,14675,0,14674,13719,13718,12795,12794,11903,11902,11042,11044,11046,11048,11050,11052,11054,11056,0,11058,11060,11062,11064,11066,11068,11070,11072,11074,11076,11078,11080,11082,11084,11086,0,11088,11090,11092,11094,11096,11098,11100,11102,11104,11106,11108,11110,11112,11114,11116,0,11118,11120,11122,11124,11126,11128,11130,11132,11134,11136,11138,11140,11142,11144,11146,0,11148,11150,11152,11154,11156,11158,11160,11162,11164,11166,11168,11170,11172,11174,11176,0,11178,11180,11182,11184,11186,11188,11190,11192,11194,11196,11198,11200,11202,11204,11206,0,11208,11210,11212,11214,11216,11218,11220,11222,11224,11226,11228,11230,11232,11234,11236,0,11238,11240,11242,11244,11246,11248,11250,11252,11254,11256,12132,12133,13040,13041,13980,0,13981,14952,14953,15956,15957,16992,16993,18060,18061,19160,19161, + 19933,19932,18817,18816,17733,17732,16681,16680,15661,15660,14673,1,14672,13717,13716,12793,12792,11901,11900,11041,11040,10211,10213,10215,10217,10219,10221,1,10223,10225,10227,10229,10231,10233,10235,10237,10239,10241,10243,10245,10247,10249,10251,1,10253,10255,10257,10259,10261,10263,10265,10267,10269,10271,10273,10275,10277,10279,10281,1,10283,10285,10287,10289,10291,10293,10295,10297,10299,10301,10303,10305,10307,10309,10311,1,10313,10315,10317,10319,10321,10323,10325,10327,10329,10331,10333,10335,10337,10339,10341,1,10343,10345,10347,10349,10351,10353,10355,10357,10359,10361,10363,10365,10367,10369,10371,1,10373,10375,10377,10379,10381,10383,10385,10387,10389,10391,10393,10395,10397,10399,10401,1,10403,10405,10407,10409,10411,10413,10415,10417,11258,11259,12134,12135,13042,13043,13982,1,13983,14954,14955,15958,15959,16994,16995,18062,18063,19162,19163, + 19931,19930,18815,18814,17731,17730,16679,16678,15659,15658,14671,0,14670,13715,13714,12791,12790,11899,11898,11039,11038,10210,10212,10214,10216,10218,10220,0,10222,10224,10226,10228,10230,10232,10234,10236,10238,10240,10242,10244,10246,10248,10250,0,10252,10254,10256,10258,10260,10262,10264,10266,10268,10270,10272,10274,10276,10278,10280,0,10282,10284,10286,10288,10290,10292,10294,10296,10298,10300,10302,10304,10306,10308,10310,0,10312,10314,10316,10318,10320,10322,10324,10326,10328,10330,10332,10334,10336,10338,10340,0,10342,10344,10346,10348,10350,10352,10354,10356,10358,10360,10362,10364,10366,10368,10370,0,10372,10374,10376,10378,10380,10382,10384,10386,10388,10390,10392,10394,10396,10398,10400,0,10402,10404,10406,10408,10410,10412,10414,10416,11260,11261,12136,12137,13044,13045,13984,0,13985,14956,14957,15960,15961,16996,16997,18064,18065,19164,19165, + 19929,19928,18813,18812,17729,17728,16677,16676,15657,15656,14669,1,14668,13713,13712,12789,12788,11897,11896,11037,11036,10209,10208,9411,9413,9415,9417,1,9419,9421,9423,9425,9427,9429,9431,9433,9435,9437,9439,9441,9443,9445,9447,1,9449,9451,9453,9455,9457,9459,9461,9463,9465,9467,9469,9471,9473,9475,9477,1,9479,9481,9483,9485,9487,9489,9491,9493,9495,9497,9499,9501,9503,9505,9507,1,9509,9511,9513,9515,9517,9519,9521,9523,9525,9527,9529,9531,9533,9535,9537,1,9539,9541,9543,9545,9547,9549,9551,9553,9555,9557,9559,9561,9563,9565,9567,1,9569,9571,9573,9575,9577,9579,9581,9583,9585,9587,9589,9591,9593,9595,9597,1,9599,9601,9603,9605,9607,9609,10418,10419,11262,11263,12138,12139,13046,13047,13986,1,13987,14958,14959,15962,15963,16998,16999,18066,18067,19166,19167, + 19927,19926,18811,18810,17727,17726,16675,16674,15655,15654,14667,0,14666,13711,13710,12787,12786,11895,11894,11035,11034,10207,10206,9410,9412,9414,9416,0,9418,9420,9422,9424,9426,9428,9430,9432,9434,9436,9438,9440,9442,9444,9446,0,9448,9450,9452,9454,9456,9458,9460,9462,9464,9466,9468,9470,9472,9474,9476,0,9478,9480,9482,9484,9486,9488,9490,9492,9494,9496,9498,9500,9502,9504,9506,0,9508,9510,9512,9514,9516,9518,9520,9522,9524,9526,9528,9530,9532,9534,9536,0,9538,9540,9542,9544,9546,9548,9550,9552,9554,9556,9558,9560,9562,9564,9566,0,9568,9570,9572,9574,9576,9578,9580,9582,9584,9586,9588,9590,9592,9594,9596,0,9598,9600,9602,9604,9606,9608,10420,10421,11264,11265,12140,12141,13048,13049,13988,0,13989,14960,14961,15964,15965,17000,17001,18068,18069,19168,19169, + 19925,19924,18809,18808,17725,17724,16673,16672,15653,15652,14665,1,14664,13709,13708,12785,12784,11893,11892,11033,11032,10205,10204,9409,9408,8643,8645,1,8647,8649,8651,8653,8655,8657,8659,8661,8663,8665,8667,8669,8671,8673,8675,1,8677,8679,8681,8683,8685,8687,8689,8691,8693,8695,8697,8699,8701,8703,8705,1,8707,8709,8711,8713,8715,8717,8719,8721,8723,8725,8727,8729,8731,8733,8735,1,8737,8739,8741,8743,8745,8747,8749,8751,8753,8755,8757,8759,8761,8763,8765,1,8767,8769,8771,8773,8775,8777,8779,8781,8783,8785,8787,8789,8791,8793,8795,1,8797,8799,8801,8803,8805,8807,8809,8811,8813,8815,8817,8819,8821,8823,8825,1,8827,8829,8831,8833,9610,9611,10422,10423,11266,11267,12142,12143,13050,13051,13990,1,13991,14962,14963,15966,15967,17002,17003,18070,18071,19170,19171, + 19923,19922,18807,18806,17723,17722,16671,16670,15651,15650,14663,0,14662,13707,13706,12783,12782,11891,11890,11031,11030,10203,10202,9407,9406,8642,8644,0,8646,8648,8650,8652,8654,8656,8658,8660,8662,8664,8666,8668,8670,8672,8674,0,8676,8678,8680,8682,8684,8686,8688,8690,8692,8694,8696,8698,8700,8702,8704,0,8706,8708,8710,8712,8714,8716,8718,8720,8722,8724,8726,8728,8730,8732,8734,0,8736,8738,8740,8742,8744,8746,8748,8750,8752,8754,8756,8758,8760,8762,8764,0,8766,8768,8770,8772,8774,8776,8778,8780,8782,8784,8786,8788,8790,8792,8794,0,8796,8798,8800,8802,8804,8806,8808,8810,8812,8814,8816,8818,8820,8822,8824,0,8826,8828,8830,8832,9612,9613,10424,10425,11268,11269,12144,12145,13052,13053,13992,0,13993,14964,14965,15968,15969,17004,17005,18072,18073,19172,19173, + 19921,19920,18805,18804,17721,17720,16669,16668,15649,15648,14661,1,14660,13705,13704,12781,12780,11889,11888,11029,11028,10201,10200,9405,9404,8641,8640,1,7907,7909,7911,7913,7915,7917,7919,7921,7923,7925,7927,7929,7931,7933,7935,1,7937,7939,7941,7943,7945,7947,7949,7951,7953,7955,7957,7959,7961,7963,7965,1,7967,7969,7971,7973,7975,7977,7979,7981,7983,7985,7987,7989,7991,7993,7995,1,7997,7999,8001,8003,8005,8007,8009,8011,8013,8015,8017,8019,8021,8023,8025,1,8027,8029,8031,8033,8035,8037,8039,8041,8043,8045,8047,8049,8051,8053,8055,1,8057,8059,8061,8063,8065,8067,8069,8071,8073,8075,8077,8079,8081,8083,8085,1,8087,8089,8834,8835,9614,9615,10426,10427,11270,11271,12146,12147,13054,13055,13994,1,13995,14966,14967,15970,15971,17006,17007,18074,18075,19174,19175, + 19919,19918,18803,18802,17719,17718,16667,16666,15647,15646,14659,0,14658,13703,13702,12779,12778,11887,11886,11027,11026,10199,10198,9403,9402,8639,8638,0,7906,7908,7910,7912,7914,7916,7918,7920,7922,7924,7926,7928,7930,7932,7934,0,7936,7938,7940,7942,7944,7946,7948,7950,7952,7954,7956,7958,7960,7962,7964,0,7966,7968,7970,7972,7974,7976,7978,7980,7982,7984,7986,7988,7990,7992,7994,0,7996,7998,8000,8002,8004,8006,8008,8010,8012,8014,8016,8018,8020,8022,8024,0,8026,8028,8030,8032,8034,8036,8038,8040,8042,8044,8046,8048,8050,8052,8054,0,8056,8058,8060,8062,8064,8066,8068,8070,8072,8074,8076,8078,8080,8082,8084,0,8086,8088,8836,8837,9616,9617,10428,10429,11272,11273,12148,12149,13056,13057,13996,0,13997,14968,14969,15972,15973,17008,17009,18076,18077,19176,19177, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19917,19916,18801,18800,17717,17716,16665,16664,15645,15644,14657,0,14656,13701,13700,12777,12776,11885,11884,11025,11024,10197,10196,9401,9400,8637,8636,0,7905,7904,7203,7205,7207,7209,7211,7213,7215,7217,7219,7221,7223,7225,7227,0,7229,7231,7233,7235,7237,7239,7241,7243,7245,7247,7249,7251,7253,7255,7257,0,7259,7261,7263,7265,7267,7269,7271,7273,7275,7277,7279,7281,7283,7285,7287,0,7289,7291,7293,7295,7297,7299,7301,7303,7305,7307,7309,7311,7313,7315,7317,0,7319,7321,7323,7325,7327,7329,7331,7333,7335,7337,7339,7341,7343,7345,7347,0,7349,7351,7353,7355,7357,7359,7361,7363,7365,7367,7369,7371,7373,7375,7377,0,8090,8091,8838,8839,9618,9619,10430,10431,11274,11275,12150,12151,13058,13059,13998,0,13999,14970,14971,15974,15975,17010,17011,18078,18079,19178,19179, + 19915,19914,18799,18798,17715,17714,16663,16662,15643,15642,14655,1,14654,13699,13698,12775,12774,11883,11882,11023,11022,10195,10194,9399,9398,8635,8634,1,7903,7902,7202,7204,7206,7208,7210,7212,7214,7216,7218,7220,7222,7224,7226,1,7228,7230,7232,7234,7236,7238,7240,7242,7244,7246,7248,7250,7252,7254,7256,1,7258,7260,7262,7264,7266,7268,7270,7272,7274,7276,7278,7280,7282,7284,7286,1,7288,7290,7292,7294,7296,7298,7300,7302,7304,7306,7308,7310,7312,7314,7316,1,7318,7320,7322,7324,7326,7328,7330,7332,7334,7336,7338,7340,7342,7344,7346,1,7348,7350,7352,7354,7356,7358,7360,7362,7364,7366,7368,7370,7372,7374,7376,1,8092,8093,8840,8841,9620,9621,10432,10433,11276,11277,12152,12153,13060,13061,14000,1,14001,14972,14973,15976,15977,17012,17013,18080,18081,19180,19181, + 19913,19912,18797,18796,17713,17712,16661,16660,15641,15640,14653,0,14652,13697,13696,12773,12772,11881,11880,11021,11020,10193,10192,9397,9396,8633,8632,0,7901,7900,7201,7200,6531,6533,6535,6537,6539,6541,6543,6545,6547,6549,6551,0,6553,6555,6557,6559,6561,6563,6565,6567,6569,6571,6573,6575,6577,6579,6581,0,6583,6585,6587,6589,6591,6593,6595,6597,6599,6601,6603,6605,6607,6609,6611,0,6613,6615,6617,6619,6621,6623,6625,6627,6629,6631,6633,6635,6637,6639,6641,0,6643,6645,6647,6649,6651,6653,6655,6657,6659,6661,6663,6665,6667,6669,6671,0,6673,6675,6677,6679,6681,6683,6685,6687,6689,6691,6693,6695,6697,7378,7379,0,8094,8095,8842,8843,9622,9623,10434,10435,11278,11279,12154,12155,13062,13063,14002,0,14003,14974,14975,15978,15979,17014,17015,18082,18083,19182,19183, + 19911,19910,18795,18794,17711,17710,16659,16658,15639,15638,14651,1,14650,13695,13694,12771,12770,11879,11878,11019,11018,10191,10190,9395,9394,8631,8630,1,7899,7898,7199,7198,6530,6532,6534,6536,6538,6540,6542,6544,6546,6548,6550,1,6552,6554,6556,6558,6560,6562,6564,6566,6568,6570,6572,6574,6576,6578,6580,1,6582,6584,6586,6588,6590,6592,6594,6596,6598,6600,6602,6604,6606,6608,6610,1,6612,6614,6616,6618,6620,6622,6624,6626,6628,6630,6632,6634,6636,6638,6640,1,6642,6644,6646,6648,6650,6652,6654,6656,6658,6660,6662,6664,6666,6668,6670,1,6672,6674,6676,6678,6680,6682,6684,6686,6688,6690,6692,6694,6696,7380,7381,1,8096,8097,8844,8845,9624,9625,10436,10437,11280,11281,12156,12157,13064,13065,14004,1,14005,14976,14977,15980,15981,17016,17017,18084,18085,19184,19185, + 19909,19908,18793,18792,17709,17708,16657,16656,15637,15636,14649,0,14648,13693,13692,12769,12768,11877,11876,11017,11016,10189,10188,9393,9392,8629,8628,0,7897,7896,7197,7196,6529,6528,5891,5893,5895,5897,5899,5901,5903,5905,5907,0,5909,5911,5913,5915,5917,5919,5921,5923,5925,5927,5929,5931,5933,5935,5937,0,5939,5941,5943,5945,5947,5949,5951,5953,5955,5957,5959,5961,5963,5965,5967,0,5969,5971,5973,5975,5977,5979,5981,5983,5985,5987,5989,5991,5993,5995,5997,0,5999,6001,6003,6005,6007,6009,6011,6013,6015,6017,6019,6021,6023,6025,6027,0,6029,6031,6033,6035,6037,6039,6041,6043,6045,6047,6049,6698,6699,7382,7383,0,8098,8099,8846,8847,9626,9627,10438,10439,11282,11283,12158,12159,13066,13067,14006,0,14007,14978,14979,15982,15983,17018,17019,18086,18087,19186,19187, + 19907,19906,18791,18790,17707,17706,16655,16654,15635,15634,14647,1,14646,13691,13690,12767,12766,11875,11874,11015,11014,10187,10186,9391,9390,8627,8626,1,7895,7894,7195,7194,6527,6526,5890,5892,5894,5896,5898,5900,5902,5904,5906,1,5908,5910,5912,5914,5916,5918,5920,5922,5924,5926,5928,5930,5932,5934,5936,1,5938,5940,5942,5944,5946,5948,5950,5952,5954,5956,5958,5960,5962,5964,5966,1,5968,5970,5972,5974,5976,5978,5980,5982,5984,5986,5988,5990,5992,5994,5996,1,5998,6000,6002,6004,6006,6008,6010,6012,6014,6016,6018,6020,6022,6024,6026,1,6028,6030,6032,6034,6036,6038,6040,6042,6044,6046,6048,6700,6701,7384,7385,1,8100,8101,8848,8849,9628,9629,10440,10441,11284,11285,12160,12161,13068,13069,14008,1,14009,14980,14981,15984,15985,17020,17021,18088,18089,19188,19189, + 19905,19904,18789,18788,17705,17704,16653,16652,15633,15632,14645,0,14644,13689,13688,12765,12764,11873,11872,11013,11012,10185,10184,9389,9388,8625,8624,0,7893,7892,7193,7192,6525,6524,5889,5888,5283,5285,5287,5289,5291,5293,5295,0,5297,5299,5301,5303,5305,5307,5309,5311,5313,5315,5317,5319,5321,5323,5325,0,5327,5329,5331,5333,5335,5337,5339,5341,5343,5345,5347,5349,5351,5353,5355,0,5357,5359,5361,5363,5365,5367,5369,5371,5373,5375,5377,5379,5381,5383,5385,0,5387,5389,5391,5393,5395,5397,5399,5401,5403,5405,5407,5409,5411,5413,5415,0,5417,5419,5421,5423,5425,5427,5429,5431,5433,6050,6051,6702,6703,7386,7387,0,8102,8103,8850,8851,9630,9631,10442,10443,11286,11287,12162,12163,13070,13071,14010,0,14011,14982,14983,15986,15987,17022,17023,18090,18091,19190,19191, + 19903,19902,18787,18786,17703,17702,16651,16650,15631,15630,14643,1,14642,13687,13686,12763,12762,11871,11870,11011,11010,10183,10182,9387,9386,8623,8622,1,7891,7890,7191,7190,6523,6522,5887,5886,5282,5284,5286,5288,5290,5292,5294,1,5296,5298,5300,5302,5304,5306,5308,5310,5312,5314,5316,5318,5320,5322,5324,1,5326,5328,5330,5332,5334,5336,5338,5340,5342,5344,5346,5348,5350,5352,5354,1,5356,5358,5360,5362,5364,5366,5368,5370,5372,5374,5376,5378,5380,5382,5384,1,5386,5388,5390,5392,5394,5396,5398,5400,5402,5404,5406,5408,5410,5412,5414,1,5416,5418,5420,5422,5424,5426,5428,5430,5432,6052,6053,6704,6705,7388,7389,1,8104,8105,8852,8853,9632,9633,10444,10445,11288,11289,12164,12165,13072,13073,14012,1,14013,14984,14985,15988,15989,17024,17025,18092,18093,19192,19193, + 19901,19900,18785,18784,17701,17700,16649,16648,15629,15628,14641,0,14640,13685,13684,12761,12760,11869,11868,11009,11008,10181,10180,9385,9384,8621,8620,0,7889,7888,7189,7188,6521,6520,5885,5884,5281,5280,4707,4709,4711,4713,4715,0,4717,4719,4721,4723,4725,4727,4729,4731,4733,4735,4737,4739,4741,4743,4745,0,4747,4749,4751,4753,4755,4757,4759,4761,4763,4765,4767,4769,4771,4773,4775,0,4777,4779,4781,4783,4785,4787,4789,4791,4793,4795,4797,4799,4801,4803,4805,0,4807,4809,4811,4813,4815,4817,4819,4821,4823,4825,4827,4829,4831,4833,4835,0,4837,4839,4841,4843,4845,4847,4849,5434,5435,6054,6055,6706,6707,7390,7391,0,8106,8107,8854,8855,9634,9635,10446,10447,11290,11291,12166,12167,13074,13075,14014,0,14015,14986,14987,15990,15991,17026,17027,18094,18095,19194,19195, + 19899,19898,18783,18782,17699,17698,16647,16646,15627,15626,14639,1,14638,13683,13682,12759,12758,11867,11866,11007,11006,10179,10178,9383,9382,8619,8618,1,7887,7886,7187,7186,6519,6518,5883,5882,5279,5278,4706,4708,4710,4712,4714,1,4716,4718,4720,4722,4724,4726,4728,4730,4732,4734,4736,4738,4740,4742,4744,1,4746,4748,4750,4752,4754,4756,4758,4760,4762,4764,4766,4768,4770,4772,4774,1,4776,4778,4780,4782,4784,4786,4788,4790,4792,4794,4796,4798,4800,4802,4804,1,4806,4808,4810,4812,4814,4816,4818,4820,4822,4824,4826,4828,4830,4832,4834,1,4836,4838,4840,4842,4844,4846,4848,5436,5437,6056,6057,6708,6709,7392,7393,1,8108,8109,8856,8857,9636,9637,10448,10449,11292,11293,12168,12169,13076,13077,14016,1,14017,14988,14989,15992,15993,17028,17029,18096,18097,19196,19197, + 19897,19896,18781,18780,17697,17696,16645,16644,15625,15624,14637,0,14636,13681,13680,12757,12756,11865,11864,11005,11004,10177,10176,9381,9380,8617,8616,0,7885,7884,7185,7184,6517,6516,5881,5880,5277,5276,4705,4704,4163,4165,4167,0,4169,4171,4173,4175,4177,4179,4181,4183,4185,4187,4189,4191,4193,4195,4197,0,4199,4201,4203,4205,4207,4209,4211,4213,4215,4217,4219,4221,4223,4225,4227,0,4229,4231,4233,4235,4237,4239,4241,4243,4245,4247,4249,4251,4253,4255,4257,0,4259,4261,4263,4265,4267,4269,4271,4273,4275,4277,4279,4281,4283,4285,4287,0,4289,4291,4293,4295,4297,4850,4851,5438,5439,6058,6059,6710,6711,7394,7395,0,8110,8111,8858,8859,9638,9639,10450,10451,11294,11295,12170,12171,13078,13079,14018,0,14019,14990,14991,15994,15995,17030,17031,18098,18099,19198,19199, + 19895,19894,18779,18778,17695,17694,16643,16642,15623,15622,14635,1,14634,13679,13678,12755,12754,11863,11862,11003,11002,10175,10174,9379,9378,8615,8614,1,7883,7882,7183,7182,6515,6514,5879,5878,5275,5274,4703,4702,4162,4164,4166,1,4168,4170,4172,4174,4176,4178,4180,4182,4184,4186,4188,4190,4192,4194,4196,1,4198,4200,4202,4204,4206,4208,4210,4212,4214,4216,4218,4220,4222,4224,4226,1,4228,4230,4232,4234,4236,4238,4240,4242,4244,4246,4248,4250,4252,4254,4256,1,4258,4260,4262,4264,4266,4268,4270,4272,4274,4276,4278,4280,4282,4284,4286,1,4288,4290,4292,4294,4296,4852,4853,5440,5441,6060,6061,6712,6713,7396,7397,1,8112,8113,8860,8861,9640,9641,10452,10453,11296,11297,12172,12173,13080,13081,14020,1,14021,14992,14993,15996,15997,17032,17033,18100,18101,19200,19201, + 19893,19892,18777,18776,17693,17692,16641,16640,15621,15620,14633,0,14632,13677,13676,12753,12752,11861,11860,11001,11000,10173,10172,9377,9376,8613,8612,0,7881,7880,7181,7180,6513,6512,5877,5876,5273,5272,4701,4700,4161,4160,3651,0,3653,3655,3657,3659,3661,3663,3665,3667,3669,3671,3673,3675,3677,3679,3681,0,3683,3685,3687,3689,3691,3693,3695,3697,3699,3701,3703,3705,3707,3709,3711,0,3713,3715,3717,3719,3721,3723,3725,3727,3729,3731,3733,3735,3737,3739,3741,0,3743,3745,3747,3749,3751,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771,0,3773,3775,3777,4298,4299,4854,4855,5442,5443,6062,6063,6714,6715,7398,7399,0,8114,8115,8862,8863,9642,9643,10454,10455,11298,11299,12174,12175,13082,13083,14022,0,14023,14994,14995,15998,15999,17034,17035,18102,18103,19202,19203, + 19891,19890,18775,18774,17691,17690,16639,16638,15619,15618,14631,1,14630,13675,13674,12751,12750,11859,11858,10999,10998,10171,10170,9375,9374,8611,8610,1,7879,7878,7179,7178,6511,6510,5875,5874,5271,5270,4699,4698,4159,4158,3650,1,3652,3654,3656,3658,3660,3662,3664,3666,3668,3670,3672,3674,3676,3678,3680,1,3682,3684,3686,3688,3690,3692,3694,3696,3698,3700,3702,3704,3706,3708,3710,1,3712,3714,3716,3718,3720,3722,3724,3726,3728,3730,3732,3734,3736,3738,3740,1,3742,3744,3746,3748,3750,3752,3754,3756,3758,3760,3762,3764,3766,3768,3770,1,3772,3774,3776,4300,4301,4856,4857,5444,5445,6064,6065,6716,6717,7400,7401,1,8116,8117,8864,8865,9644,9645,10456,10457,11300,11301,12176,12177,13084,13085,14024,1,14025,14996,14997,16000,16001,17036,17037,18104,18105,19204,19205, + 19889,19888,18773,18772,17689,17688,16637,16636,15617,15616,14629,0,14628,13673,13672,12749,12748,11857,11856,10997,10996,10169,10168,9373,9372,8609,8608,0,7877,7876,7177,7176,6509,6508,5873,5872,5269,5268,4697,4696,4157,4156,3649,0,3648,3171,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195,3197,0,3199,3201,3203,3205,3207,3209,3211,3213,3215,3217,3219,3221,3223,3225,3227,0,3229,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257,0,3259,3261,3263,3265,3267,3269,3271,3273,3275,3277,3279,3281,3283,3285,3287,0,3289,3778,3779,4302,4303,4858,4859,5446,5447,6066,6067,6718,6719,7402,7403,0,8118,8119,8866,8867,9646,9647,10458,10459,11302,11303,12178,12179,13086,13087,14026,0,14027,14998,14999,16002,16003,17038,17039,18106,18107,19206,19207, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19887,19886,18771,18770,17687,17686,16635,16634,15615,15614,14627,0,14626,13671,13670,12747,12746,11855,11854,10995,10994,10167,10166,9371,9370,8607,8606,0,7875,7874,7175,7174,6507,6506,5871,5870,5267,5266,4695,4694,4155,4154,3647,0,3646,3170,3172,3174,3176,3178,3180,3182,3184,3186,3188,3190,3192,3194,3196,0,3198,3200,3202,3204,3206,3208,3210,3212,3214,3216,3218,3220,3222,3224,3226,0,3228,3230,3232,3234,3236,3238,3240,3242,3244,3246,3248,3250,3252,3254,3256,0,3258,3260,3262,3264,3266,3268,3270,3272,3274,3276,3278,3280,3282,3284,3286,0,3288,3780,3781,4304,4305,4860,4861,5448,5449,6068,6069,6720,6721,7404,7405,0,8120,8121,8868,8869,9648,9649,10460,10461,11304,11305,12180,12181,13088,13089,14028,0,14029,15000,15001,16004,16005,17040,17041,18108,18109,19208,19209, + 19885,19884,18769,18768,17685,17684,16633,16632,15613,15612,14625,1,14624,13669,13668,12745,12744,11853,11852,10993,10992,10165,10164,9369,9368,8605,8604,1,7873,7872,7173,7172,6505,6504,5869,5868,5265,5264,4693,4692,4153,4152,3645,1,3644,3169,3168,2723,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,1,2747,2749,2751,2753,2755,2757,2759,2761,2763,2765,2767,2769,2771,2773,2775,1,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,1,2807,2809,2811,2813,2815,2817,2819,2821,2823,2825,2827,2829,2831,2833,3290,1,3291,3782,3783,4306,4307,4862,4863,5450,5451,6070,6071,6722,6723,7406,7407,1,8122,8123,8870,8871,9650,9651,10462,10463,11306,11307,12182,12183,13090,13091,14030,1,14031,15002,15003,16006,16007,17042,17043,18110,18111,19210,19211, + 19883,19882,18767,18766,17683,17682,16631,16630,15611,15610,14623,0,14622,13667,13666,12743,12742,11851,11850,10991,10990,10163,10162,9367,9366,8603,8602,0,7871,7870,7171,7170,6503,6502,5867,5866,5263,5262,4691,4690,4151,4150,3643,0,3642,3167,3166,2722,2724,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,0,2746,2748,2750,2752,2754,2756,2758,2760,2762,2764,2766,2768,2770,2772,2774,0,2776,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800,2802,2804,0,2806,2808,2810,2812,2814,2816,2818,2820,2822,2824,2826,2828,2830,2832,3292,0,3293,3784,3785,4308,4309,4864,4865,5452,5453,6072,6073,6724,6725,7408,7409,0,8124,8125,8872,8873,9652,9653,10464,10465,11308,11309,12184,12185,13092,13093,14032,0,14033,15004,15005,16008,16009,17044,17045,18112,18113,19212,19213, + 19881,19880,18765,18764,17681,17680,16629,16628,15609,15608,14621,1,14620,13665,13664,12741,12740,11849,11848,10989,10988,10161,10160,9365,9364,8601,8600,1,7869,7868,7169,7168,6501,6500,5865,5864,5261,5260,4689,4688,4149,4148,3641,1,3640,3165,3164,2721,2720,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325,1,2327,2329,2331,2333,2335,2337,2339,2341,2343,2345,2347,2349,2351,2353,2355,1,2357,2359,2361,2363,2365,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385,1,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405,2407,2409,2834,2835,3294,1,3295,3786,3787,4310,4311,4866,4867,5454,5455,6074,6075,6726,6727,7410,7411,1,8126,8127,8874,8875,9654,9655,10466,10467,11310,11311,12186,12187,13094,13095,14034,1,14035,15006,15007,16010,16011,17046,17047,18114,18115,19214,19215, + 19879,19878,18763,18762,17679,17678,16627,16626,15607,15606,14619,0,14618,13663,13662,12739,12738,11847,11846,10987,10986,10159,10158,9363,9362,8599,8598,0,7867,7866,7167,7166,6499,6498,5863,5862,5259,5258,4687,4686,4147,4146,3639,0,3638,3163,3162,2719,2718,2306,2308,2310,2312,2314,2316,2318,2320,2322,2324,0,2326,2328,2330,2332,2334,2336,2338,2340,2342,2344,2346,2348,2350,2352,2354,0,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374,2376,2378,2380,2382,2384,0,2386,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2836,2837,3296,0,3297,3788,3789,4312,4313,4868,4869,5456,5457,6076,6077,6728,6729,7412,7413,0,8128,8129,8876,8877,9656,9657,10468,10469,11312,11313,12188,12189,13096,13097,14036,0,14037,15008,15009,16012,16013,17048,17049,18116,18117,19216,19217, + 19877,19876,18761,18760,17677,17676,16625,16624,15605,15604,14617,1,14616,13661,13660,12737,12736,11845,11844,10985,10984,10157,10156,9361,9360,8597,8596,1,7865,7864,7165,7164,6497,6496,5861,5860,5257,5256,4685,4684,4145,4144,3637,1,3636,3161,3160,2717,2716,2305,2304,1923,1925,1927,1929,1931,1933,1935,1937,1,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991,1993,1995,1997,1,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2410,2411,2838,2839,3298,1,3299,3790,3791,4314,4315,4870,4871,5458,5459,6078,6079,6730,6731,7414,7415,1,8130,8131,8878,8879,9658,9659,10470,10471,11314,11315,12190,12191,13098,13099,14038,1,14039,15010,15011,16014,16015,17050,17051,18118,18119,19218,19219, + 19875,19874,18759,18758,17675,17674,16623,16622,15603,15602,14615,0,14614,13659,13658,12735,12734,11843,11842,10983,10982,10155,10154,9359,9358,8595,8594,0,7863,7862,7163,7162,6495,6494,5859,5858,5255,5254,4683,4682,4143,4142,3635,0,3634,3159,3158,2715,2714,2303,2302,1922,1924,1926,1928,1930,1932,1934,1936,0,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1962,1964,1966,0,1968,1970,1972,1974,1976,1978,1980,1982,1984,1986,1988,1990,1992,1994,1996,0,1998,2000,2002,2004,2006,2008,2010,2012,2014,2016,2412,2413,2840,2841,3300,0,3301,3792,3793,4316,4317,4872,4873,5460,5461,6080,6081,6732,6733,7416,7417,0,8132,8133,8880,8881,9660,9661,10472,10473,11316,11317,12192,12193,13100,13101,14040,0,14041,15012,15013,16016,16017,17052,17053,18120,18121,19220,19221, + 19873,19872,18757,18756,17673,17672,16621,16620,15601,15600,14613,1,14612,13657,13656,12733,12732,11841,11840,10981,10980,10153,10152,9357,9356,8593,8592,1,7861,7860,7161,7160,6493,6492,5857,5856,5253,5252,4681,4680,4141,4140,3633,1,3632,3157,3156,2713,2712,2301,2300,1921,1920,1571,1573,1575,1577,1579,1581,1,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611,1,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1,1643,1645,1647,1649,1651,1653,1655,1657,2018,2019,2414,2415,2842,2843,3302,1,3303,3794,3795,4318,4319,4874,4875,5462,5463,6082,6083,6734,6735,7418,7419,1,8134,8135,8882,8883,9662,9663,10474,10475,11318,11319,12194,12195,13102,13103,14042,1,14043,15014,15015,16018,16019,17054,17055,18122,18123,19222,19223, + 19871,19870,18755,18754,17671,17670,16619,16618,15599,15598,14611,0,14610,13655,13654,12731,12730,11839,11838,10979,10978,10151,10150,9355,9354,8591,8590,0,7859,7858,7159,7158,6491,6490,5855,5854,5251,5250,4679,4678,4139,4138,3631,0,3630,3155,3154,2711,2710,2299,2298,1919,1918,1570,1572,1574,1576,1578,1580,0,1582,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610,0,1612,1614,1616,1618,1620,1622,1624,1626,1628,1630,1632,1634,1636,1638,1640,0,1642,1644,1646,1648,1650,1652,1654,1656,2020,2021,2416,2417,2844,2845,3304,0,3305,3796,3797,4320,4321,4876,4877,5464,5465,6084,6085,6736,6737,7420,7421,0,8136,8137,8884,8885,9664,9665,10476,10477,11320,11321,12196,12197,13104,13105,14044,0,14045,15016,15017,16020,16021,17056,17057,18124,18125,19224,19225, + 19869,19868,18753,18752,17669,17668,16617,16616,15597,15596,14609,1,14608,13653,13652,12729,12728,11837,11836,10977,10976,10149,10148,9353,9352,8589,8588,1,7857,7856,7157,7156,6489,6488,5853,5852,5249,5248,4677,4676,4137,4136,3629,1,3628,3153,3152,2709,2708,2297,2296,1917,1916,1569,1568,1251,1253,1255,1257,1,1259,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309,1311,1313,1315,1317,1,1319,1321,1323,1325,1327,1329,1658,1659,2022,2023,2418,2419,2846,2847,3306,1,3307,3798,3799,4322,4323,4878,4879,5466,5467,6086,6087,6738,6739,7422,7423,1,8138,8139,8886,8887,9666,9667,10478,10479,11322,11323,12198,12199,13106,13107,14046,1,14047,15018,15019,16022,16023,17058,17059,18126,18127,19226,19227, + 19867,19866,18751,18750,17667,17666,16615,16614,15595,15594,14607,0,14606,13651,13650,12727,12726,11835,11834,10975,10974,10147,10146,9351,9350,8587,8586,0,7855,7854,7155,7154,6487,6486,5851,5850,5247,5246,4675,4674,4135,4134,3627,0,3626,3151,3150,2707,2706,2295,2294,1915,1914,1567,1566,1250,1252,1254,1256,0,1258,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1286,0,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314,1316,0,1318,1320,1322,1324,1326,1328,1660,1661,2024,2025,2420,2421,2848,2849,3308,0,3309,3800,3801,4324,4325,4880,4881,5468,5469,6088,6089,6740,6741,7424,7425,0,8140,8141,8888,8889,9668,9669,10480,10481,11324,11325,12200,12201,13108,13109,14048,0,14049,15020,15021,16024,16025,17060,17061,18128,18129,19228,19229, + 19865,19864,18749,18748,17665,17664,16613,16612,15593,15592,14605,1,14604,13649,13648,12725,12724,11833,11832,10973,10972,10145,10144,9349,9348,8585,8584,1,7853,7852,7153,7152,6485,6484,5849,5848,5245,5244,4673,4672,4133,4132,3625,1,3624,3149,3148,2705,2704,2293,2292,1913,1912,1565,1564,1249,1248,963,965,1,967,969,971,973,975,977,979,981,983,985,987,989,991,993,995,1,997,999,1001,1003,1005,1007,1009,1011,1013,1015,1017,1019,1021,1023,1025,1,1027,1029,1031,1033,1330,1331,1662,1663,2026,2027,2422,2423,2850,2851,3310,1,3311,3802,3803,4326,4327,4882,4883,5470,5471,6090,6091,6742,6743,7426,7427,1,8142,8143,8890,8891,9670,9671,10482,10483,11326,11327,12202,12203,13110,13111,14050,1,14051,15022,15023,16026,16027,17062,17063,18130,18131,19230,19231, + 19863,19862,18747,18746,17663,17662,16611,16610,15591,15590,14603,0,14602,13647,13646,12723,12722,11831,11830,10971,10970,10143,10142,9347,9346,8583,8582,0,7851,7850,7151,7150,6483,6482,5847,5846,5243,5242,4671,4670,4131,4130,3623,0,3622,3147,3146,2703,2702,2291,2290,1911,1910,1563,1562,1247,1246,962,964,0,966,968,970,972,974,976,978,980,982,984,986,988,990,992,994,0,996,998,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,0,1026,1028,1030,1032,1332,1333,1664,1665,2028,2029,2424,2425,2852,2853,3312,0,3313,3804,3805,4328,4329,4884,4885,5472,5473,6092,6093,6744,6745,7428,7429,0,8144,8145,8892,8893,9672,9673,10484,10485,11328,11329,12204,12205,13112,13113,14052,0,14053,15024,15025,16028,16029,17064,17065,18132,18133,19232,19233, + 19861,19860,18745,18744,17661,17660,16609,16608,15589,15588,14601,1,14600,13645,13644,12721,12720,11829,11828,10969,10968,10141,10140,9345,9344,8581,8580,1,7849,7848,7149,7148,6481,6480,5845,5844,5241,5240,4669,4668,4129,4128,3621,1,3620,3145,3144,2701,2700,2289,2288,1909,1908,1561,1560,1245,1244,961,960,1,707,709,711,713,715,717,719,721,723,725,727,729,731,733,735,1,737,739,741,743,745,747,749,751,753,755,757,759,761,763,765,1,767,769,1034,1035,1334,1335,1666,1667,2030,2031,2426,2427,2854,2855,3314,1,3315,3806,3807,4330,4331,4886,4887,5474,5475,6094,6095,6746,6747,7430,7431,1,8146,8147,8894,8895,9674,9675,10486,10487,11330,11331,12206,12207,13114,13115,14054,1,14055,15026,15027,16030,16031,17066,17067,18134,18135,19234,19235, + 19859,19858,18743,18742,17659,17658,16607,16606,15587,15586,14599,0,14598,13643,13642,12719,12718,11827,11826,10967,10966,10139,10138,9343,9342,8579,8578,0,7847,7846,7147,7146,6479,6478,5843,5842,5239,5238,4667,4666,4127,4126,3619,0,3618,3143,3142,2699,2698,2287,2286,1907,1906,1559,1558,1243,1242,959,958,0,706,708,710,712,714,716,718,720,722,724,726,728,730,732,734,0,736,738,740,742,744,746,748,750,752,754,756,758,760,762,764,0,766,768,1036,1037,1336,1337,1668,1669,2032,2033,2428,2429,2856,2857,3316,0,3317,3808,3809,4332,4333,4888,4889,5476,5477,6096,6097,6748,6749,7432,7433,0,8148,8149,8896,8897,9676,9677,10488,10489,11332,11333,12208,12209,13116,13117,14056,0,14057,15028,15029,16032,16033,17068,17069,18136,18137,19236,19237, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19857,19856,18741,18740,17657,17656,16605,16604,15585,15584,14597,0,14596,13641,13640,12717,12716,11825,11824,10965,10964,10137,10136,9341,9340,8577,8576,0,7845,7844,7145,7144,6477,6476,5841,5840,5237,5236,4665,4664,4125,4124,3617,0,3616,3141,3140,2697,2696,2285,2284,1905,1904,1557,1556,1241,1240,957,956,0,705,704,483,485,487,489,491,493,495,497,499,501,503,505,507,0,509,511,513,515,517,519,521,523,525,527,529,531,533,535,537,0,770,771,1038,1039,1338,1339,1670,1671,2034,2035,2430,2431,2858,2859,3318,0,3319,3810,3811,4334,4335,4890,4891,5478,5479,6098,6099,6750,6751,7434,7435,0,8150,8151,8898,8899,9678,9679,10490,10491,11334,11335,12210,12211,13118,13119,14058,0,14059,15030,15031,16034,16035,17070,17071,18138,18139,19238,19239, + 19855,19854,18739,18738,17655,17654,16603,16602,15583,15582,14595,1,14594,13639,13638,12715,12714,11823,11822,10963,10962,10135,10134,9339,9338,8575,8574,1,7843,7842,7143,7142,6475,6474,5839,5838,5235,5234,4663,4662,4123,4122,3615,1,3614,3139,3138,2695,2694,2283,2282,1903,1902,1555,1554,1239,1238,955,954,1,703,702,482,484,486,488,490,492,494,496,498,500,502,504,506,1,508,510,512,514,516,518,520,522,524,526,528,530,532,534,536,1,772,773,1040,1041,1340,1341,1672,1673,2036,2037,2432,2433,2860,2861,3320,1,3321,3812,3813,4336,4337,4892,4893,5480,5481,6100,6101,6752,6753,7436,7437,1,8152,8153,8900,8901,9680,9681,10492,10493,11336,11337,12212,12213,13120,13121,14060,1,14061,15032,15033,16036,16037,17072,17073,18140,18141,19240,19241, + 19853,19852,18737,18736,17653,17652,16601,16600,15581,15580,14593,0,14592,13637,13636,12713,12712,11821,11820,10961,10960,10133,10132,9337,9336,8573,8572,0,7841,7840,7141,7140,6473,6472,5837,5836,5233,5232,4661,4660,4121,4120,3613,0,3612,3137,3136,2693,2692,2281,2280,1901,1900,1553,1552,1237,1236,953,952,0,701,700,481,480,291,293,295,297,299,301,303,305,307,309,311,0,313,315,317,319,321,323,325,327,329,331,333,335,337,538,539,0,774,775,1042,1043,1342,1343,1674,1675,2038,2039,2434,2435,2862,2863,3322,0,3323,3814,3815,4338,4339,4894,4895,5482,5483,6102,6103,6754,6755,7438,7439,0,8154,8155,8902,8903,9682,9683,10494,10495,11338,11339,12214,12215,13122,13123,14062,0,14063,15034,15035,16038,16039,17074,17075,18142,18143,19242,19243, + 19851,19850,18735,18734,17651,17650,16599,16598,15579,15578,14591,1,14590,13635,13634,12711,12710,11819,11818,10959,10958,10131,10130,9335,9334,8571,8570,1,7839,7838,7139,7138,6471,6470,5835,5834,5231,5230,4659,4658,4119,4118,3611,1,3610,3135,3134,2691,2690,2279,2278,1899,1898,1551,1550,1235,1234,951,950,1,699,698,479,478,290,292,294,296,298,300,302,304,306,308,310,1,312,314,316,318,320,322,324,326,328,330,332,334,336,540,541,1,776,777,1044,1045,1344,1345,1676,1677,2040,2041,2436,2437,2864,2865,3324,1,3325,3816,3817,4340,4341,4896,4897,5484,5485,6104,6105,6756,6757,7440,7441,1,8156,8157,8904,8905,9684,9685,10496,10497,11340,11341,12216,12217,13124,13125,14064,1,14065,15036,15037,16040,16041,17076,17077,18144,18145,19244,19245, + 19849,19848,18733,18732,17649,17648,16597,16596,15577,15576,14589,0,14588,13633,13632,12709,12708,11817,11816,10957,10956,10129,10128,9333,9332,8569,8568,0,7837,7836,7137,7136,6469,6468,5833,5832,5229,5228,4657,4656,4117,4116,3609,0,3608,3133,3132,2689,2688,2277,2276,1897,1896,1549,1548,1233,1232,949,948,0,697,696,477,476,289,288,131,133,135,137,139,141,143,145,147,0,149,151,153,155,157,159,161,163,165,167,169,338,339,542,543,0,778,779,1046,1047,1346,1347,1678,1679,2042,2043,2438,2439,2866,2867,3326,0,3327,3818,3819,4342,4343,4898,4899,5486,5487,6106,6107,6758,6759,7442,7443,0,8158,8159,8906,8907,9686,9687,10498,10499,11342,11343,12218,12219,13126,13127,14066,0,14067,15038,15039,16042,16043,17078,17079,18146,18147,19246,19247, + 19847,19846,18731,18730,17647,17646,16595,16594,15575,15574,14587,1,14586,13631,13630,12707,12706,11815,11814,10955,10954,10127,10126,9331,9330,8567,8566,1,7835,7834,7135,7134,6467,6466,5831,5830,5227,5226,4655,4654,4115,4114,3607,1,3606,3131,3130,2687,2686,2275,2274,1895,1894,1547,1546,1231,1230,947,946,1,695,694,475,474,287,286,130,132,134,136,138,140,142,144,146,1,148,150,152,154,156,158,160,162,164,166,168,340,341,544,545,1,780,781,1048,1049,1348,1349,1680,1681,2044,2045,2440,2441,2868,2869,3328,1,3329,3820,3821,4344,4345,4900,4901,5488,5489,6108,6109,6760,6761,7444,7445,1,8160,8161,8908,8909,9688,9689,10500,10501,11344,11345,12220,12221,13128,13129,14068,1,14069,15040,15041,16044,16045,17080,17081,18148,18149,19248,19249, + 19845,19844,18729,18728,17645,17644,16593,16592,15573,15572,14585,0,14584,13629,13628,12705,12704,11813,11812,10953,10952,10125,10124,9329,9328,8565,8564,0,7833,7832,7133,7132,6465,6464,5829,5828,5225,5224,4653,4652,4113,4112,3605,0,3604,3129,3128,2685,2684,2273,2272,1893,1892,1545,1544,1229,1228,945,944,0,693,692,473,472,285,284,129,128,3,5,7,9,11,13,15,0,17,19,21,23,25,27,29,31,33,170,171,342,343,546,547,0,782,783,1050,1051,1350,1351,1682,1683,2046,2047,2442,2443,2870,2871,3330,0,3331,3822,3823,4346,4347,4902,4903,5490,5491,6110,6111,6762,6763,7446,7447,0,8162,8163,8910,8911,9690,9691,10502,10503,11346,11347,12222,12223,13130,13131,14070,0,14071,15042,15043,16046,16047,17082,17083,18150,18151,19250,19251, + 19843,19842,18727,18726,17643,17642,16591,16590,15571,15570,14583,1,14582,13627,13626,12703,12702,11811,11810,10951,10950,10123,10122,9327,9326,8563,8562,1,7831,7830,7131,7130,6463,6462,5827,5826,5223,5222,4651,4650,4111,4110,3603,1,3602,3127,3126,2683,2682,2271,2270,1891,1890,1543,1542,1227,1226,943,942,1,691,690,471,470,283,282,127,126,2,4,6,8,10,12,14,1,16,18,20,22,24,26,28,30,32,172,173,344,345,548,549,1,784,785,1052,1053,1352,1353,1684,1685,2048,2049,2444,2445,2872,2873,3332,1,3333,3824,3825,4348,4349,4904,4905,5492,5493,6112,6113,6764,6765,7448,7449,1,8164,8165,8912,8913,9692,9693,10504,10505,11348,11349,12224,12225,13132,13133,14072,1,14073,15044,15045,16048,16049,17084,17085,18152,18153,19252,19253, + 19841,19840,18725,18724,17641,17640,16589,16588,15569,15568,14581,0,14580,13625,13624,12701,12700,11809,11808,10949,10948,10121,10120,9325,9324,8561,8560,0,7829,7828,7129,7128,6461,6460,5825,5824,5221,5220,4649,4648,4109,4108,3601,0,3600,3125,3124,2681,2680,2269,2268,1889,1888,1541,1540,1225,1224,941,940,0,689,688,469,468,281,280,125,124,1,1,20000,20001,20002,20003,20004,0,20005,20006,20007,20008,20009,0,1,34,35,174,175,346,347,550,551,0,786,787,1054,1055,1354,1355,1686,1687,2050,2051,2446,2447,2874,2875,3334,0,3335,3826,3827,4350,4351,4906,4907,5494,5495,6114,6115,6766,6767,7450,7451,0,8166,8167,8914,8915,9694,9695,10506,10507,11350,11351,12226,12227,13134,13135,14074,0,14075,15046,15047,16050,16051,17086,17087,18154,18155,19254,19255, + 19839,19838,18723,18722,17639,17638,16587,16586,15567,15566,14579,1,14578,13623,13622,12699,12698,11807,11806,10947,10946,10119,10118,9323,9322,8559,8558,1,7827,7826,7127,7126,6459,6458,5823,5822,5219,5218,4647,4646,4107,4106,3599,1,3598,3123,3122,2679,2678,2267,2266,1887,1886,1539,1538,1223,1222,939,938,1,687,686,467,466,279,278,123,122,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,37,176,177,348,349,552,553,1,788,789,1056,1057,1356,1357,1688,1689,2052,2053,2448,2449,2876,2877,3336,1,3337,3828,3829,4352,4353,4908,4909,5496,5497,6116,6117,6768,6769,7452,7453,1,8168,8169,8916,8917,9696,9697,10508,10509,11352,11353,12228,12229,13136,13137,14076,1,14077,15048,15049,16052,16053,17088,17089,18156,18157,19256,19257, + 19837,19836,18721,18720,17637,17636,16585,16584,15565,15564,14577,0,14576,13621,13620,12697,12696,11805,11804,10945,10944,10117,10116,9321,9320,8557,8556,0,7825,7824,7125,7124,6457,6456,5821,5820,5217,5216,4645,4644,4105,4104,3597,0,3596,3121,3120,2677,2676,2265,2264,1885,1884,1537,1536,1221,1220,937,936,0,685,684,465,464,277,276,121,120,20039,1,0,0,0,0,0,0,0,0,0,0,0,1,20010,38,39,178,179,350,351,554,555,0,790,791,1058,1059,1358,1359,1690,1691,2054,2055,2450,2451,2878,2879,3338,0,3339,3830,3831,4354,4355,4910,4911,5498,5499,6118,6119,6770,6771,7454,7455,0,8170,8171,8918,8919,9698,9699,10510,10511,11354,11355,12230,12231,13138,13139,14078,0,14079,15050,15051,16054,16055,17090,17091,18158,18159,19258,19259, + 19835,19834,18719,18718,17635,17634,16583,16582,15563,15562,14575,1,14574,13619,13618,12695,12694,11803,11802,10943,10942,10115,10114,9319,9318,8555,8554,1,7823,7822,7123,7122,6455,6454,5819,5818,5215,5214,4643,4642,4103,4102,3595,1,3594,3119,3118,2675,2674,2263,2262,1883,1882,1535,1534,1219,1218,935,934,1,683,682,463,462,275,274,119,118,20038,1,0,1,1,1,1,1,1,1,1,1,0,1,20011,40,41,180,181,352,353,556,557,1,792,793,1060,1061,1360,1361,1692,1693,2056,2057,2452,2453,2880,2881,3340,1,3341,3832,3833,4356,4357,4912,4913,5500,5501,6120,6121,6772,6773,7456,7457,1,8172,8173,8920,8921,9700,9701,10512,10513,11356,11357,12232,12233,13140,13141,14080,1,14081,15052,15053,16056,16057,17092,17093,18160,18161,19260,19261, + 19833,19832,18717,18716,17633,17632,16581,16580,15561,15560,14573,0,14572,13617,13616,12693,12692,11801,11800,10941,10940,10113,10112,9317,9316,8553,8552,0,7821,7820,7121,7120,6453,6452,5817,5816,5213,5212,4641,4640,4101,4100,3593,0,3592,3117,3116,2673,2672,2261,2260,1881,1880,1533,1532,1217,1216,933,932,0,681,680,461,460,273,272,117,116,20037,1,0,1,0,0,0,0,0,0,0,1,0,1,20012,42,43,182,183,354,355,558,559,0,794,795,1062,1063,1362,1363,1694,1695,2058,2059,2454,2455,2882,2883,3342,0,3343,3834,3835,4358,4359,4914,4915,5502,5503,6122,6123,6774,6775,7458,7459,0,8174,8175,8922,8923,9702,9703,10514,10515,11358,11359,12234,12235,13142,13143,14082,0,14083,15054,15055,16058,16059,17094,17095,18162,18163,19262,19263, + 19831,19830,18715,18714,17631,17630,16579,16578,15559,15558,14571,1,14570,13615,13614,12691,12690,11799,11798,10939,10938,10111,10110,9315,9314,8551,8550,1,7819,7818,7119,7118,6451,6450,5815,5814,5211,5210,4639,4638,4099,4098,3591,1,3590,3115,3114,2671,2670,2259,2258,1879,1878,1531,1530,1215,1214,931,930,1,679,678,459,458,271,270,115,114,20036,1,0,1,0,1,1,1,1,1,0,1,0,1,20013,44,45,184,185,356,357,560,561,1,796,797,1064,1065,1364,1365,1696,1697,2060,2061,2456,2457,2884,2885,3344,1,3345,3836,3837,4360,4361,4916,4917,5504,5505,6124,6125,6776,6777,7460,7461,1,8176,8177,8924,8925,9704,9705,10516,10517,11360,11361,12236,12237,13144,13145,14084,1,14085,15056,15057,16060,16061,17096,17097,18164,18165,19264,19265, + 19829,19828,18713,18712,17629,17628,16577,16576,15557,15556,14569,0,14568,13613,13612,12689,12688,11797,11796,10937,10936,10109,10108,9313,9312,8549,8548,0,7817,7816,7117,7116,6449,6448,5813,5812,5209,5208,4637,4636,4097,4096,3589,0,3588,3113,3112,2669,2668,2257,2256,1877,1876,1529,1528,1213,1212,929,928,0,677,676,457,456,269,268,113,112,20035,1,0,1,0,1,0,0,0,1,0,1,0,1,20014,46,47,186,187,358,359,562,563,0,798,799,1066,1067,1366,1367,1698,1699,2062,2063,2458,2459,2886,2887,3346,0,3347,3838,3839,4362,4363,4918,4919,5506,5507,6126,6127,6778,6779,7462,7463,0,8178,8179,8926,8927,9706,9707,10518,10519,11362,11363,12238,12239,13146,13147,14086,0,14087,15058,15059,16062,16063,17098,17099,18166,18167,19266,19267, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19827,19826,18711,18710,17627,17626,16575,16574,15555,15554,14567,0,14566,13611,13610,12687,12686,11795,11794,10935,10934,10107,10106,9311,9310,8547,8546,0,7815,7814,7115,7114,6447,6446,5811,5810,5207,5206,4635,4634,4095,4094,3587,0,3586,3111,3110,2667,2666,2255,2254,1875,1874,1527,1526,1211,1210,927,926,0,675,674,455,454,267,266,111,110,20034,1,0,1,0,1,0,0,0,1,0,1,0,1,20015,48,49,188,189,360,361,564,565,0,800,801,1068,1069,1368,1369,1700,1701,2064,2065,2460,2461,2888,2889,3348,0,3349,3840,3841,4364,4365,4920,4921,5508,5509,6128,6129,6780,6781,7464,7465,0,8180,8181,8928,8929,9708,9709,10520,10521,11364,11365,12240,12241,13148,13149,14088,0,14089,15060,15061,16064,16065,17100,17101,18168,18169,19268,19269, + 19825,19824,18709,18708,17625,17624,16573,16572,15553,15552,14565,1,14564,13609,13608,12685,12684,11793,11792,10933,10932,10105,10104,9309,9308,8545,8544,1,7813,7812,7113,7112,6445,6444,5809,5808,5205,5204,4633,4632,4093,4092,3585,1,3584,3109,3108,2665,2664,2253,2252,1873,1872,1525,1524,1209,1208,925,924,1,673,672,453,452,265,264,109,108,20033,1,0,1,0,1,1,1,1,1,0,1,0,1,20016,50,51,190,191,362,363,566,567,1,802,803,1070,1071,1370,1371,1702,1703,2066,2067,2462,2463,2890,2891,3350,1,3351,3842,3843,4366,4367,4922,4923,5510,5511,6130,6131,6782,6783,7466,7467,1,8182,8183,8930,8931,9710,9711,10522,10523,11366,11367,12242,12243,13150,13151,14090,1,14091,15062,15063,16066,16067,17102,17103,18170,18171,19270,19271, + 19823,19822,18707,18706,17623,17622,16571,16570,15551,15550,14563,0,14562,13607,13606,12683,12682,11791,11790,10931,10930,10103,10102,9307,9306,8543,8542,0,7811,7810,7111,7110,6443,6442,5807,5806,5203,5202,4631,4630,4091,4090,3583,0,3582,3107,3106,2663,2662,2251,2250,1871,1870,1523,1522,1207,1206,923,922,0,671,670,451,450,263,262,107,106,20032,1,0,1,0,0,0,0,0,0,0,1,0,1,20017,52,53,192,193,364,365,568,569,0,804,805,1072,1073,1372,1373,1704,1705,2068,2069,2464,2465,2892,2893,3352,0,3353,3844,3845,4368,4369,4924,4925,5512,5513,6132,6133,6784,6785,7468,7469,0,8184,8185,8932,8933,9712,9713,10524,10525,11368,11369,12244,12245,13152,13153,14092,0,14093,15064,15065,16068,16069,17104,17105,18172,18173,19272,19273, + 19821,19820,18705,18704,17621,17620,16569,16568,15549,15548,14561,1,14560,13605,13604,12681,12680,11789,11788,10929,10928,10101,10100,9305,9304,8541,8540,1,7809,7808,7109,7108,6441,6440,5805,5804,5201,5200,4629,4628,4089,4088,3581,1,3580,3105,3104,2661,2660,2249,2248,1869,1868,1521,1520,1205,1204,921,920,1,669,668,449,448,261,260,105,104,20031,1,0,1,1,1,1,1,1,1,1,1,0,1,20018,54,55,194,195,366,367,570,571,1,806,807,1074,1075,1374,1375,1706,1707,2070,2071,2466,2467,2894,2895,3354,1,3355,3846,3847,4370,4371,4926,4927,5514,5515,6134,6135,6786,6787,7470,7471,1,8186,8187,8934,8935,9714,9715,10526,10527,11370,11371,12246,12247,13154,13155,14094,1,14095,15066,15067,16070,16071,17106,17107,18174,18175,19274,19275, + 19819,19818,18703,18702,17619,17618,16567,16566,15547,15546,14559,0,14558,13603,13602,12679,12678,11787,11786,10927,10926,10099,10098,9303,9302,8539,8538,0,7807,7806,7107,7106,6439,6438,5803,5802,5199,5198,4627,4626,4087,4086,3579,0,3578,3103,3102,2659,2658,2247,2246,1867,1866,1519,1518,1203,1202,919,918,0,667,666,447,446,259,258,103,102,20030,1,0,0,0,0,0,0,0,0,0,0,0,1,20019,56,57,196,197,368,369,572,573,0,808,809,1076,1077,1376,1377,1708,1709,2072,2073,2468,2469,2896,2897,3356,0,3357,3848,3849,4372,4373,4928,4929,5516,5517,6136,6137,6788,6789,7472,7473,0,8188,8189,8936,8937,9716,9717,10528,10529,11372,11373,12248,12249,13156,13157,14096,0,14097,15068,15069,16072,16073,17108,17109,18176,18177,19276,19277, + 19817,19816,18701,18700,17617,17616,16565,16564,15545,15544,14557,1,14556,13601,13600,12677,12676,11785,11784,10925,10924,10097,10096,9301,9300,8537,8536,1,7805,7804,7105,7104,6437,6436,5801,5800,5197,5196,4625,4624,4085,4084,3577,1,3576,3101,3100,2657,2656,2245,2244,1865,1864,1517,1516,1201,1200,917,916,1,665,664,445,444,257,256,101,100,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,58,59,198,199,370,371,574,575,1,810,811,1078,1079,1378,1379,1710,1711,2074,2075,2470,2471,2898,2899,3358,1,3359,3850,3851,4374,4375,4930,4931,5518,5519,6138,6139,6790,6791,7474,7475,1,8190,8191,8938,8939,9718,9719,10530,10531,11374,11375,12250,12251,13158,13159,14098,1,14099,15070,15071,16074,16075,17110,17111,18178,18179,19278,19279, + 19815,19814,18699,18698,17615,17614,16563,16562,15543,15542,14555,0,14554,13599,13598,12675,12674,11783,11782,10923,10922,10095,10094,9299,9298,8535,8534,0,7803,7802,7103,7102,6435,6434,5799,5798,5195,5194,4623,4622,4083,4082,3575,0,3574,3099,3098,2655,2654,2243,2242,1863,1862,1515,1514,1199,1198,915,914,0,663,662,443,442,255,254,99,98,0,0,20029,20028,20027,20026,20025,0,20024,20023,20022,20021,20020,0,0,60,61,200,201,372,373,576,577,0,812,813,1080,1081,1380,1381,1712,1713,2076,2077,2472,2473,2900,2901,3360,0,3361,3852,3853,4376,4377,4932,4933,5520,5521,6140,6141,6792,6793,7476,7477,0,8192,8193,8940,8941,9720,9721,10532,10533,11376,11377,12252,12253,13160,13161,14100,0,14101,15072,15073,16076,16077,17112,17113,18180,18181,19280,19281, + 19813,19812,18697,18696,17613,17612,16561,16560,15541,15540,14553,1,14552,13597,13596,12673,12672,11781,11780,10921,10920,10093,10092,9297,9296,8533,8532,1,7801,7800,7101,7100,6433,6432,5797,5796,5193,5192,4621,4620,4081,4080,3573,1,3572,3097,3096,2653,2652,2241,2240,1861,1860,1513,1512,1197,1196,913,912,1,661,660,441,440,253,252,96,94,92,90,88,86,84,82,80,1,78,76,74,72,70,68,66,62,63,202,203,374,375,578,579,1,814,815,1082,1083,1382,1383,1714,1715,2078,2079,2474,2475,2902,2903,3362,1,3363,3854,3855,4378,4379,4934,4935,5522,5523,6142,6143,6794,6795,7478,7479,1,8194,8195,8942,8943,9722,9723,10534,10535,11378,11379,12254,12255,13162,13163,14102,1,14103,15074,15075,16078,16079,17114,17115,18182,18183,19282,19283, + 19811,19810,18695,18694,17611,17610,16559,16558,15539,15538,14551,0,14550,13595,13594,12671,12670,11779,11778,10919,10918,10091,10090,9295,9294,8531,8530,0,7799,7798,7099,7098,6431,6430,5795,5794,5191,5190,4619,4618,4079,4078,3571,0,3570,3095,3094,2651,2650,2239,2238,1859,1858,1511,1510,1195,1194,911,910,0,659,658,439,438,251,250,97,95,93,91,89,87,85,83,81,0,79,77,75,73,71,69,67,64,65,204,205,376,377,580,581,0,816,817,1084,1085,1384,1385,1716,1717,2080,2081,2476,2477,2904,2905,3364,0,3365,3856,3857,4380,4381,4936,4937,5524,5525,6144,6145,6796,6797,7480,7481,0,8196,8197,8944,8945,9724,9725,10536,10537,11380,11381,12256,12257,13164,13165,14104,0,14105,15076,15077,16080,16081,17116,17117,18184,18185,19284,19285, + 19809,19808,18693,18692,17609,17608,16557,16556,15537,15536,14549,1,14548,13593,13592,12669,12668,11777,11776,10917,10916,10089,10088,9293,9292,8529,8528,1,7797,7796,7097,7096,6429,6428,5793,5792,5189,5188,4617,4616,4077,4076,3569,1,3568,3093,3092,2649,2648,2237,2236,1857,1856,1509,1508,1193,1192,909,908,1,657,656,437,436,248,246,244,242,240,238,236,234,232,230,228,1,226,224,222,220,218,216,214,212,210,206,207,378,379,582,583,1,818,819,1086,1087,1386,1387,1718,1719,2082,2083,2478,2479,2906,2907,3366,1,3367,3858,3859,4382,4383,4938,4939,5526,5527,6146,6147,6798,6799,7482,7483,1,8198,8199,8946,8947,9726,9727,10538,10539,11382,11383,12258,12259,13166,13167,14106,1,14107,15078,15079,16082,16083,17118,17119,18186,18187,19286,19287, + 19807,19806,18691,18690,17607,17606,16555,16554,15535,15534,14547,0,14546,13591,13590,12667,12666,11775,11774,10915,10914,10087,10086,9291,9290,8527,8526,0,7795,7794,7095,7094,6427,6426,5791,5790,5187,5186,4615,4614,4075,4074,3567,0,3566,3091,3090,2647,2646,2235,2234,1855,1854,1507,1506,1191,1190,907,906,0,655,654,435,434,249,247,245,243,241,239,237,235,233,231,229,0,227,225,223,221,219,217,215,213,211,208,209,380,381,584,585,0,820,821,1088,1089,1388,1389,1720,1721,2084,2085,2480,2481,2908,2909,3368,0,3369,3860,3861,4384,4385,4940,4941,5528,5529,6148,6149,6800,6801,7484,7485,0,8200,8201,8948,8949,9728,9729,10540,10541,11384,11385,12260,12261,13168,13169,14108,0,14109,15080,15081,16084,16085,17120,17121,18188,18189,19288,19289, + 19805,19804,18689,18688,17605,17604,16553,16552,15533,15532,14545,1,14544,13589,13588,12665,12664,11773,11772,10913,10912,10085,10084,9289,9288,8525,8524,1,7793,7792,7093,7092,6425,6424,5789,5788,5185,5184,4613,4612,4073,4072,3565,1,3564,3089,3088,2645,2644,2233,2232,1853,1852,1505,1504,1189,1188,905,904,1,653,652,432,430,428,426,424,422,420,418,416,414,412,410,408,1,406,404,402,400,398,396,394,392,390,388,386,382,383,586,587,1,822,823,1090,1091,1390,1391,1722,1723,2086,2087,2482,2483,2910,2911,3370,1,3371,3862,3863,4386,4387,4942,4943,5530,5531,6150,6151,6802,6803,7486,7487,1,8202,8203,8950,8951,9730,9731,10542,10543,11386,11387,12262,12263,13170,13171,14110,1,14111,15082,15083,16086,16087,17122,17123,18190,18191,19290,19291, + 19803,19802,18687,18686,17603,17602,16551,16550,15531,15530,14543,0,14542,13587,13586,12663,12662,11771,11770,10911,10910,10083,10082,9287,9286,8523,8522,0,7791,7790,7091,7090,6423,6422,5787,5786,5183,5182,4611,4610,4071,4070,3563,0,3562,3087,3086,2643,2642,2231,2230,1851,1850,1503,1502,1187,1186,903,902,0,651,650,433,431,429,427,425,423,421,419,417,415,413,411,409,0,407,405,403,401,399,397,395,393,391,389,387,384,385,588,589,0,824,825,1092,1093,1392,1393,1724,1725,2088,2089,2484,2485,2912,2913,3372,0,3373,3864,3865,4388,4389,4944,4945,5532,5533,6152,6153,6804,6805,7488,7489,0,8204,8205,8952,8953,9732,9733,10544,10545,11388,11389,12264,12265,13172,13173,14112,0,14113,15084,15085,16088,16089,17124,17125,18192,18193,19292,19293, + 19801,19800,18685,18684,17601,17600,16549,16548,15529,15528,14541,1,14540,13585,13584,12661,12660,11769,11768,10909,10908,10081,10080,9285,9284,8521,8520,1,7789,7788,7089,7088,6421,6420,5785,5784,5181,5180,4609,4608,4069,4068,3561,1,3560,3085,3084,2641,2640,2229,2228,1849,1848,1501,1500,1185,1184,901,900,1,648,646,644,642,640,638,636,634,632,630,628,626,624,622,620,1,618,616,614,612,610,608,606,604,602,600,598,596,594,590,591,1,826,827,1094,1095,1394,1395,1726,1727,2090,2091,2486,2487,2914,2915,3374,1,3375,3866,3867,4390,4391,4946,4947,5534,5535,6154,6155,6806,6807,7490,7491,1,8206,8207,8954,8955,9734,9735,10546,10547,11390,11391,12266,12267,13174,13175,14114,1,14115,15086,15087,16090,16091,17126,17127,18194,18195,19294,19295, + 19799,19798,18683,18682,17599,17598,16547,16546,15527,15526,14539,0,14538,13583,13582,12659,12658,11767,11766,10907,10906,10079,10078,9283,9282,8519,8518,0,7787,7786,7087,7086,6419,6418,5783,5782,5179,5178,4607,4606,4067,4066,3559,0,3558,3083,3082,2639,2638,2227,2226,1847,1846,1499,1498,1183,1182,899,898,0,649,647,645,643,641,639,637,635,633,631,629,627,625,623,621,0,619,617,615,613,611,609,607,605,603,601,599,597,595,592,593,0,828,829,1096,1097,1396,1397,1728,1729,2092,2093,2488,2489,2916,2917,3376,0,3377,3868,3869,4392,4393,4948,4949,5536,5537,6156,6157,6808,6809,7492,7493,0,8208,8209,8956,8957,9736,9737,10548,10549,11392,11393,12268,12269,13176,13177,14116,0,14117,15088,15089,16092,16093,17128,17129,18196,18197,19296,19297, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19797,19796,18681,18680,17597,17596,16545,16544,15525,15524,14537,0,14536,13581,13580,12657,12656,11765,11764,10905,10904,10077,10076,9281,9280,8517,8516,0,7785,7784,7085,7084,6417,6416,5781,5780,5177,5176,4605,4604,4065,4064,3557,0,3556,3081,3080,2637,2636,2225,2224,1845,1844,1497,1496,1181,1180,896,894,0,892,890,888,886,884,882,880,878,876,874,872,870,868,866,864,0,862,860,858,856,854,852,850,848,846,844,842,840,838,836,834,0,830,831,1098,1099,1398,1399,1730,1731,2094,2095,2490,2491,2918,2919,3378,0,3379,3870,3871,4394,4395,4950,4951,5538,5539,6158,6159,6810,6811,7494,7495,0,8210,8211,8958,8959,9738,9739,10550,10551,11394,11395,12270,12271,13178,13179,14118,0,14119,15090,15091,16094,16095,17130,17131,18198,18199,19298,19299, + 19795,19794,18679,18678,17595,17594,16543,16542,15523,15522,14535,1,14534,13579,13578,12655,12654,11763,11762,10903,10902,10075,10074,9279,9278,8515,8514,1,7783,7782,7083,7082,6415,6414,5779,5778,5175,5174,4603,4602,4063,4062,3555,1,3554,3079,3078,2635,2634,2223,2222,1843,1842,1495,1494,1179,1178,897,895,1,893,891,889,887,885,883,881,879,877,875,873,871,869,867,865,1,863,861,859,857,855,853,851,849,847,845,843,841,839,837,835,1,832,833,1100,1101,1400,1401,1732,1733,2096,2097,2492,2493,2920,2921,3380,1,3381,3872,3873,4396,4397,4952,4953,5540,5541,6160,6161,6812,6813,7496,7497,1,8212,8213,8960,8961,9740,9741,10552,10553,11396,11397,12272,12273,13180,13181,14120,1,14121,15092,15093,16096,16097,17132,17133,18200,18201,19300,19301, + 19793,19792,18677,18676,17593,17592,16541,16540,15521,15520,14533,0,14532,13577,13576,12653,12652,11761,11760,10901,10900,10073,10072,9277,9276,8513,8512,0,7781,7780,7081,7080,6413,6412,5777,5776,5173,5172,4601,4600,4061,4060,3553,0,3552,3077,3076,2633,2632,2221,2220,1841,1840,1493,1492,1176,1174,1172,1170,0,1168,1166,1164,1162,1160,1158,1156,1154,1152,1150,1148,1146,1144,1142,1140,0,1138,1136,1134,1132,1130,1128,1126,1124,1122,1120,1118,1116,1114,1112,1110,0,1108,1106,1102,1103,1402,1403,1734,1735,2098,2099,2494,2495,2922,2923,3382,0,3383,3874,3875,4398,4399,4954,4955,5542,5543,6162,6163,6814,6815,7498,7499,0,8214,8215,8962,8963,9742,9743,10554,10555,11398,11399,12274,12275,13182,13183,14122,0,14123,15094,15095,16098,16099,17134,17135,18202,18203,19302,19303, + 19791,19790,18675,18674,17591,17590,16539,16538,15519,15518,14531,1,14530,13575,13574,12651,12650,11759,11758,10899,10898,10071,10070,9275,9274,8511,8510,1,7779,7778,7079,7078,6411,6410,5775,5774,5171,5170,4599,4598,4059,4058,3551,1,3550,3075,3074,2631,2630,2219,2218,1839,1838,1491,1490,1177,1175,1173,1171,1,1169,1167,1165,1163,1161,1159,1157,1155,1153,1151,1149,1147,1145,1143,1141,1,1139,1137,1135,1133,1131,1129,1127,1125,1123,1121,1119,1117,1115,1113,1111,1,1109,1107,1104,1105,1404,1405,1736,1737,2100,2101,2496,2497,2924,2925,3384,1,3385,3876,3877,4400,4401,4956,4957,5544,5545,6164,6165,6816,6817,7500,7501,1,8216,8217,8964,8965,9744,9745,10556,10557,11400,11401,12276,12277,13184,13185,14124,1,14125,15096,15097,16100,16101,17136,17137,18204,18205,19304,19305, + 19789,19788,18673,18672,17589,17588,16537,16536,15517,15516,14529,0,14528,13573,13572,12649,12648,11757,11756,10897,10896,10069,10068,9273,9272,8509,8508,0,7777,7776,7077,7076,6409,6408,5773,5772,5169,5168,4597,4596,4057,4056,3549,0,3548,3073,3072,2629,2628,2217,2216,1837,1836,1488,1486,1484,1482,1480,1478,0,1476,1474,1472,1470,1468,1466,1464,1462,1460,1458,1456,1454,1452,1450,1448,0,1446,1444,1442,1440,1438,1436,1434,1432,1430,1428,1426,1424,1422,1420,1418,0,1416,1414,1412,1410,1406,1407,1738,1739,2102,2103,2498,2499,2926,2927,3386,0,3387,3878,3879,4402,4403,4958,4959,5546,5547,6166,6167,6818,6819,7502,7503,0,8218,8219,8966,8967,9746,9747,10558,10559,11402,11403,12278,12279,13186,13187,14126,0,14127,15098,15099,16102,16103,17138,17139,18206,18207,19306,19307, + 19787,19786,18671,18670,17587,17586,16535,16534,15515,15514,14527,1,14526,13571,13570,12647,12646,11755,11754,10895,10894,10067,10066,9271,9270,8507,8506,1,7775,7774,7075,7074,6407,6406,5771,5770,5167,5166,4595,4594,4055,4054,3547,1,3546,3071,3070,2627,2626,2215,2214,1835,1834,1489,1487,1485,1483,1481,1479,1,1477,1475,1473,1471,1469,1467,1465,1463,1461,1459,1457,1455,1453,1451,1449,1,1447,1445,1443,1441,1439,1437,1435,1433,1431,1429,1427,1425,1423,1421,1419,1,1417,1415,1413,1411,1408,1409,1740,1741,2104,2105,2500,2501,2928,2929,3388,1,3389,3880,3881,4404,4405,4960,4961,5548,5549,6168,6169,6820,6821,7504,7505,1,8220,8221,8968,8969,9748,9749,10560,10561,11404,11405,12280,12281,13188,13189,14128,1,14129,15100,15101,16104,16105,17140,17141,18208,18209,19308,19309, + 19785,19784,18669,18668,17585,17584,16533,16532,15513,15512,14525,0,14524,13569,13568,12645,12644,11753,11752,10893,10892,10065,10064,9269,9268,8505,8504,0,7773,7772,7073,7072,6405,6404,5769,5768,5165,5164,4593,4592,4053,4052,3545,0,3544,3069,3068,2625,2624,2213,2212,1832,1830,1828,1826,1824,1822,1820,1818,0,1816,1814,1812,1810,1808,1806,1804,1802,1800,1798,1796,1794,1792,1790,1788,0,1786,1784,1782,1780,1778,1776,1774,1772,1770,1768,1766,1764,1762,1760,1758,0,1756,1754,1752,1750,1748,1746,1742,1743,2106,2107,2502,2503,2930,2931,3390,0,3391,3882,3883,4406,4407,4962,4963,5550,5551,6170,6171,6822,6823,7506,7507,0,8222,8223,8970,8971,9750,9751,10562,10563,11406,11407,12282,12283,13190,13191,14130,0,14131,15102,15103,16106,16107,17142,17143,18210,18211,19310,19311, + 19783,19782,18667,18666,17583,17582,16531,16530,15511,15510,14523,1,14522,13567,13566,12643,12642,11751,11750,10891,10890,10063,10062,9267,9266,8503,8502,1,7771,7770,7071,7070,6403,6402,5767,5766,5163,5162,4591,4590,4051,4050,3543,1,3542,3067,3066,2623,2622,2211,2210,1833,1831,1829,1827,1825,1823,1821,1819,1,1817,1815,1813,1811,1809,1807,1805,1803,1801,1799,1797,1795,1793,1791,1789,1,1787,1785,1783,1781,1779,1777,1775,1773,1771,1769,1767,1765,1763,1761,1759,1,1757,1755,1753,1751,1749,1747,1744,1745,2108,2109,2504,2505,2932,2933,3392,1,3393,3884,3885,4408,4409,4964,4965,5552,5553,6172,6173,6824,6825,7508,7509,1,8224,8225,8972,8973,9752,9753,10564,10565,11408,11409,12284,12285,13192,13193,14132,1,14133,15104,15105,16108,16109,17144,17145,18212,18213,19312,19313, + 19781,19780,18665,18664,17581,17580,16529,16528,15509,15508,14521,0,14520,13565,13564,12641,12640,11749,11748,10889,10888,10061,10060,9265,9264,8501,8500,0,7769,7768,7069,7068,6401,6400,5765,5764,5161,5160,4589,4588,4049,4048,3541,0,3540,3065,3064,2621,2620,2208,2206,2204,2202,2200,2198,2196,2194,2192,2190,0,2188,2186,2184,2182,2180,2178,2176,2174,2172,2170,2168,2166,2164,2162,2160,0,2158,2156,2154,2152,2150,2148,2146,2144,2142,2140,2138,2136,2134,2132,2130,0,2128,2126,2124,2122,2120,2118,2116,2114,2110,2111,2506,2507,2934,2935,3394,0,3395,3886,3887,4410,4411,4966,4967,5554,5555,6174,6175,6826,6827,7510,7511,0,8226,8227,8974,8975,9754,9755,10566,10567,11410,11411,12286,12287,13194,13195,14134,0,14135,15106,15107,16110,16111,17146,17147,18214,18215,19314,19315, + 19779,19778,18663,18662,17579,17578,16527,16526,15507,15506,14519,1,14518,13563,13562,12639,12638,11747,11746,10887,10886,10059,10058,9263,9262,8499,8498,1,7767,7766,7067,7066,6399,6398,5763,5762,5159,5158,4587,4586,4047,4046,3539,1,3538,3063,3062,2619,2618,2209,2207,2205,2203,2201,2199,2197,2195,2193,2191,1,2189,2187,2185,2183,2181,2179,2177,2175,2173,2171,2169,2167,2165,2163,2161,1,2159,2157,2155,2153,2151,2149,2147,2145,2143,2141,2139,2137,2135,2133,2131,1,2129,2127,2125,2123,2121,2119,2117,2115,2112,2113,2508,2509,2936,2937,3396,1,3397,3888,3889,4412,4413,4968,4969,5556,5557,6176,6177,6828,6829,7512,7513,1,8228,8229,8976,8977,9756,9757,10568,10569,11412,11413,12288,12289,13196,13197,14136,1,14137,15108,15109,16112,16113,17148,17149,18216,18217,19316,19317, + 19777,19776,18661,18660,17577,17576,16525,16524,15505,15504,14517,0,14516,13561,13560,12637,12636,11745,11744,10885,10884,10057,10056,9261,9260,8497,8496,0,7765,7764,7065,7064,6397,6396,5761,5760,5157,5156,4585,4584,4045,4044,3537,0,3536,3061,3060,2616,2614,2612,2610,2608,2606,2604,2602,2600,2598,2596,2594,0,2592,2590,2588,2586,2584,2582,2580,2578,2576,2574,2572,2570,2568,2566,2564,0,2562,2560,2558,2556,2554,2552,2550,2548,2546,2544,2542,2540,2538,2536,2534,0,2532,2530,2528,2526,2524,2522,2520,2518,2516,2514,2510,2511,2938,2939,3398,0,3399,3890,3891,4414,4415,4970,4971,5558,5559,6178,6179,6830,6831,7514,7515,0,8230,8231,8978,8979,9758,9759,10570,10571,11414,11415,12290,12291,13198,13199,14138,0,14139,15110,15111,16114,16115,17150,17151,18218,18219,19318,19319, + 19775,19774,18659,18658,17575,17574,16523,16522,15503,15502,14515,1,14514,13559,13558,12635,12634,11743,11742,10883,10882,10055,10054,9259,9258,8495,8494,1,7763,7762,7063,7062,6395,6394,5759,5758,5155,5154,4583,4582,4043,4042,3535,1,3534,3059,3058,2617,2615,2613,2611,2609,2607,2605,2603,2601,2599,2597,2595,1,2593,2591,2589,2587,2585,2583,2581,2579,2577,2575,2573,2571,2569,2567,2565,1,2563,2561,2559,2557,2555,2553,2551,2549,2547,2545,2543,2541,2539,2537,2535,1,2533,2531,2529,2527,2525,2523,2521,2519,2517,2515,2512,2513,2940,2941,3400,1,3401,3892,3893,4416,4417,4972,4973,5560,5561,6180,6181,6832,6833,7516,7517,1,8232,8233,8980,8981,9760,9761,10572,10573,11416,11417,12292,12293,13200,13201,14140,1,14141,15112,15113,16116,16117,17152,17153,18220,18221,19320,19321, + 19773,19772,18657,18656,17573,17572,16521,16520,15501,15500,14513,0,14512,13557,13556,12633,12632,11741,11740,10881,10880,10053,10052,9257,9256,8493,8492,0,7761,7760,7061,7060,6393,6392,5757,5756,5153,5152,4581,4580,4041,4040,3533,0,3532,3056,3054,3052,3050,3048,3046,3044,3042,3040,3038,3036,3034,3032,3030,0,3028,3026,3024,3022,3020,3018,3016,3014,3012,3010,3008,3006,3004,3002,3000,0,2998,2996,2994,2992,2990,2988,2986,2984,2982,2980,2978,2976,2974,2972,2970,0,2968,2966,2964,2962,2960,2958,2956,2954,2952,2950,2948,2946,2942,2943,3402,0,3403,3894,3895,4418,4419,4974,4975,5562,5563,6182,6183,6834,6835,7518,7519,0,8234,8235,8982,8983,9762,9763,10574,10575,11418,11419,12294,12295,13202,13203,14142,0,14143,15114,15115,16118,16119,17154,17155,18222,18223,19322,19323, + 19771,19770,18655,18654,17571,17570,16519,16518,15499,15498,14511,1,14510,13555,13554,12631,12630,11739,11738,10879,10878,10051,10050,9255,9254,8491,8490,1,7759,7758,7059,7058,6391,6390,5755,5754,5151,5150,4579,4578,4039,4038,3531,1,3530,3057,3055,3053,3051,3049,3047,3045,3043,3041,3039,3037,3035,3033,3031,1,3029,3027,3025,3023,3021,3019,3017,3015,3013,3011,3009,3007,3005,3003,3001,1,2999,2997,2995,2993,2991,2989,2987,2985,2983,2981,2979,2977,2975,2973,2971,1,2969,2967,2965,2963,2961,2959,2957,2955,2953,2951,2949,2947,2944,2945,3404,1,3405,3896,3897,4420,4421,4976,4977,5564,5565,6184,6185,6836,6837,7520,7521,1,8236,8237,8984,8985,9764,9765,10576,10577,11420,11421,12296,12297,13204,13205,14144,1,14145,15116,15117,16120,16121,17156,17157,18224,18225,19324,19325, + 19769,19768,18653,18652,17569,17568,16517,16516,15497,15496,14509,0,14508,13553,13552,12629,12628,11737,11736,10877,10876,10049,10048,9253,9252,8489,8488,0,7757,7756,7057,7056,6389,6388,5753,5752,5149,5148,4577,4576,4037,4036,3528,0,3526,3524,3522,3520,3518,3516,3514,3512,3510,3508,3506,3504,3502,3500,3498,0,3496,3494,3492,3490,3488,3486,3484,3482,3480,3478,3476,3474,3472,3470,3468,0,3466,3464,3462,3460,3458,3456,3454,3452,3450,3448,3446,3444,3442,3440,3438,0,3436,3434,3432,3430,3428,3426,3424,3422,3420,3418,3416,3414,3412,3410,3406,0,3407,3898,3899,4422,4423,4978,4979,5566,5567,6186,6187,6838,6839,7522,7523,0,8238,8239,8986,8987,9766,9767,10578,10579,11422,11423,12298,12299,13206,13207,14146,0,14147,15118,15119,16122,16123,17158,17159,18226,18227,19326,19327, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19767,19766,18651,18650,17567,17566,16515,16514,15495,15494,14507,0,14506,13551,13550,12627,12626,11735,11734,10875,10874,10047,10046,9251,9250,8487,8486,0,7755,7754,7055,7054,6387,6386,5751,5750,5147,5146,4575,4574,4035,4034,3529,0,3527,3525,3523,3521,3519,3517,3515,3513,3511,3509,3507,3505,3503,3501,3499,0,3497,3495,3493,3491,3489,3487,3485,3483,3481,3479,3477,3475,3473,3471,3469,0,3467,3465,3463,3461,3459,3457,3455,3453,3451,3449,3447,3445,3443,3441,3439,0,3437,3435,3433,3431,3429,3427,3425,3423,3421,3419,3417,3415,3413,3411,3408,0,3409,3900,3901,4424,4425,4980,4981,5568,5569,6188,6189,6840,6841,7524,7525,0,8240,8241,8988,8989,9768,9769,10580,10581,11424,11425,12300,12301,13208,13209,14148,0,14149,15120,15121,16124,16125,17160,17161,18228,18229,19328,19329, + 19765,19764,18649,18648,17565,17564,16513,16512,15493,15492,14505,1,14504,13549,13548,12625,12624,11733,11732,10873,10872,10045,10044,9249,9248,8485,8484,1,7753,7752,7053,7052,6385,6384,5749,5748,5145,5144,4573,4572,4032,4030,4028,1,4026,4024,4022,4020,4018,4016,4014,4012,4010,4008,4006,4004,4002,4000,3998,1,3996,3994,3992,3990,3988,3986,3984,3982,3980,3978,3976,3974,3972,3970,3968,1,3966,3964,3962,3960,3958,3956,3954,3952,3950,3948,3946,3944,3942,3940,3938,1,3936,3934,3932,3930,3928,3926,3924,3922,3920,3918,3916,3914,3912,3910,3908,1,3906,3902,3903,4426,4427,4982,4983,5570,5571,6190,6191,6842,6843,7526,7527,1,8242,8243,8990,8991,9770,9771,10582,10583,11426,11427,12302,12303,13210,13211,14150,1,14151,15122,15123,16126,16127,17162,17163,18230,18231,19330,19331, + 19763,19762,18647,18646,17563,17562,16511,16510,15491,15490,14503,0,14502,13547,13546,12623,12622,11731,11730,10871,10870,10043,10042,9247,9246,8483,8482,0,7751,7750,7051,7050,6383,6382,5747,5746,5143,5142,4571,4570,4033,4031,4029,0,4027,4025,4023,4021,4019,4017,4015,4013,4011,4009,4007,4005,4003,4001,3999,0,3997,3995,3993,3991,3989,3987,3985,3983,3981,3979,3977,3975,3973,3971,3969,0,3967,3965,3963,3961,3959,3957,3955,3953,3951,3949,3947,3945,3943,3941,3939,0,3937,3935,3933,3931,3929,3927,3925,3923,3921,3919,3917,3915,3913,3911,3909,0,3907,3904,3905,4428,4429,4984,4985,5572,5573,6192,6193,6844,6845,7528,7529,0,8244,8245,8992,8993,9772,9773,10584,10585,11428,11429,12304,12305,13212,13213,14152,0,14153,15124,15125,16128,16129,17164,17165,18232,18233,19332,19333, + 19761,19760,18645,18644,17561,17560,16509,16508,15489,15488,14501,1,14500,13545,13544,12621,12620,11729,11728,10869,10868,10041,10040,9245,9244,8481,8480,1,7749,7748,7049,7048,6381,6380,5745,5744,5141,5140,4568,4566,4564,4562,4560,1,4558,4556,4554,4552,4550,4548,4546,4544,4542,4540,4538,4536,4534,4532,4530,1,4528,4526,4524,4522,4520,4518,4516,4514,4512,4510,4508,4506,4504,4502,4500,1,4498,4496,4494,4492,4490,4488,4486,4484,4482,4480,4478,4476,4474,4472,4470,1,4468,4466,4464,4462,4460,4458,4456,4454,4452,4450,4448,4446,4444,4442,4440,1,4438,4436,4434,4430,4431,4986,4987,5574,5575,6194,6195,6846,6847,7530,7531,1,8246,8247,8994,8995,9774,9775,10586,10587,11430,11431,12306,12307,13214,13215,14154,1,14155,15126,15127,16130,16131,17166,17167,18234,18235,19334,19335, + 19759,19758,18643,18642,17559,17558,16507,16506,15487,15486,14499,0,14498,13543,13542,12619,12618,11727,11726,10867,10866,10039,10038,9243,9242,8479,8478,0,7747,7746,7047,7046,6379,6378,5743,5742,5139,5138,4569,4567,4565,4563,4561,0,4559,4557,4555,4553,4551,4549,4547,4545,4543,4541,4539,4537,4535,4533,4531,0,4529,4527,4525,4523,4521,4519,4517,4515,4513,4511,4509,4507,4505,4503,4501,0,4499,4497,4495,4493,4491,4489,4487,4485,4483,4481,4479,4477,4475,4473,4471,0,4469,4467,4465,4463,4461,4459,4457,4455,4453,4451,4449,4447,4445,4443,4441,0,4439,4437,4435,4432,4433,4988,4989,5576,5577,6196,6197,6848,6849,7532,7533,0,8248,8249,8996,8997,9776,9777,10588,10589,11432,11433,12308,12309,13216,13217,14156,0,14157,15128,15129,16132,16133,17168,17169,18236,18237,19336,19337, + 19757,19756,18641,18640,17557,17556,16505,16504,15485,15484,14497,1,14496,13541,13540,12617,12616,11725,11724,10865,10864,10037,10036,9241,9240,8477,8476,1,7745,7744,7045,7044,6377,6376,5741,5740,5136,5134,5132,5130,5128,5126,5124,1,5122,5120,5118,5116,5114,5112,5110,5108,5106,5104,5102,5100,5098,5096,5094,1,5092,5090,5088,5086,5084,5082,5080,5078,5076,5074,5072,5070,5068,5066,5064,1,5062,5060,5058,5056,5054,5052,5050,5048,5046,5044,5042,5040,5038,5036,5034,1,5032,5030,5028,5026,5024,5022,5020,5018,5016,5014,5012,5010,5008,5006,5004,1,5002,5000,4998,4996,4994,4990,4991,5578,5579,6198,6199,6850,6851,7534,7535,1,8250,8251,8998,8999,9778,9779,10590,10591,11434,11435,12310,12311,13218,13219,14158,1,14159,15130,15131,16134,16135,17170,17171,18238,18239,19338,19339, + 19755,19754,18639,18638,17555,17554,16503,16502,15483,15482,14495,0,14494,13539,13538,12615,12614,11723,11722,10863,10862,10035,10034,9239,9238,8475,8474,0,7743,7742,7043,7042,6375,6374,5739,5738,5137,5135,5133,5131,5129,5127,5125,0,5123,5121,5119,5117,5115,5113,5111,5109,5107,5105,5103,5101,5099,5097,5095,0,5093,5091,5089,5087,5085,5083,5081,5079,5077,5075,5073,5071,5069,5067,5065,0,5063,5061,5059,5057,5055,5053,5051,5049,5047,5045,5043,5041,5039,5037,5035,0,5033,5031,5029,5027,5025,5023,5021,5019,5017,5015,5013,5011,5009,5007,5005,0,5003,5001,4999,4997,4995,4992,4993,5580,5581,6200,6201,6852,6853,7536,7537,0,8252,8253,9000,9001,9780,9781,10592,10593,11436,11437,12312,12313,13220,13221,14160,0,14161,15132,15133,16136,16137,17172,17173,18240,18241,19340,19341, + 19753,19752,18637,18636,17553,17552,16501,16500,15481,15480,14493,1,14492,13537,13536,12613,12612,11721,11720,10861,10860,10033,10032,9237,9236,8473,8472,1,7741,7740,7041,7040,6373,6372,5736,5734,5732,5730,5728,5726,5724,5722,5720,1,5718,5716,5714,5712,5710,5708,5706,5704,5702,5700,5698,5696,5694,5692,5690,1,5688,5686,5684,5682,5680,5678,5676,5674,5672,5670,5668,5666,5664,5662,5660,1,5658,5656,5654,5652,5650,5648,5646,5644,5642,5640,5638,5636,5634,5632,5630,1,5628,5626,5624,5622,5620,5618,5616,5614,5612,5610,5608,5606,5604,5602,5600,1,5598,5596,5594,5592,5590,5588,5586,5582,5583,6202,6203,6854,6855,7538,7539,1,8254,8255,9002,9003,9782,9783,10594,10595,11438,11439,12314,12315,13222,13223,14162,1,14163,15134,15135,16138,16139,17174,17175,18242,18243,19342,19343, + 19751,19750,18635,18634,17551,17550,16499,16498,15479,15478,14491,0,14490,13535,13534,12611,12610,11719,11718,10859,10858,10031,10030,9235,9234,8471,8470,0,7739,7738,7039,7038,6371,6370,5737,5735,5733,5731,5729,5727,5725,5723,5721,0,5719,5717,5715,5713,5711,5709,5707,5705,5703,5701,5699,5697,5695,5693,5691,0,5689,5687,5685,5683,5681,5679,5677,5675,5673,5671,5669,5667,5665,5663,5661,0,5659,5657,5655,5653,5651,5649,5647,5645,5643,5641,5639,5637,5635,5633,5631,0,5629,5627,5625,5623,5621,5619,5617,5615,5613,5611,5609,5607,5605,5603,5601,0,5599,5597,5595,5593,5591,5589,5587,5584,5585,6204,6205,6856,6857,7540,7541,0,8256,8257,9004,9005,9784,9785,10596,10597,11440,11441,12316,12317,13224,13225,14164,0,14165,15136,15137,16140,16141,17176,17177,18244,18245,19344,19345, + 19749,19748,18633,18632,17549,17548,16497,16496,15477,15476,14489,1,14488,13533,13532,12609,12608,11717,11716,10857,10856,10029,10028,9233,9232,8469,8468,1,7737,7736,7037,7036,6368,6366,6364,6362,6360,6358,6356,6354,6352,6350,6348,1,6346,6344,6342,6340,6338,6336,6334,6332,6330,6328,6326,6324,6322,6320,6318,1,6316,6314,6312,6310,6308,6306,6304,6302,6300,6298,6296,6294,6292,6290,6288,1,6286,6284,6282,6280,6278,6276,6274,6272,6270,6268,6266,6264,6262,6260,6258,1,6256,6254,6252,6250,6248,6246,6244,6242,6240,6238,6236,6234,6232,6230,6228,1,6226,6224,6222,6220,6218,6216,6214,6212,6210,6206,6207,6858,6859,7542,7543,1,8258,8259,9006,9007,9786,9787,10598,10599,11442,11443,12318,12319,13226,13227,14166,1,14167,15138,15139,16142,16143,17178,17179,18246,18247,19346,19347, + 19747,19746,18631,18630,17547,17546,16495,16494,15475,15474,14487,0,14486,13531,13530,12607,12606,11715,11714,10855,10854,10027,10026,9231,9230,8467,8466,0,7735,7734,7035,7034,6369,6367,6365,6363,6361,6359,6357,6355,6353,6351,6349,0,6347,6345,6343,6341,6339,6337,6335,6333,6331,6329,6327,6325,6323,6321,6319,0,6317,6315,6313,6311,6309,6307,6305,6303,6301,6299,6297,6295,6293,6291,6289,0,6287,6285,6283,6281,6279,6277,6275,6273,6271,6269,6267,6265,6263,6261,6259,0,6257,6255,6253,6251,6249,6247,6245,6243,6241,6239,6237,6235,6233,6231,6229,0,6227,6225,6223,6221,6219,6217,6215,6213,6211,6208,6209,6860,6861,7544,7545,0,8260,8261,9008,9009,9788,9789,10600,10601,11444,11445,12320,12321,13228,13229,14168,0,14169,15140,15141,16144,16145,17180,17181,18248,18249,19348,19349, + 19745,19744,18629,18628,17545,17544,16493,16492,15473,15472,14485,1,14484,13529,13528,12605,12604,11713,11712,10853,10852,10025,10024,9229,9228,8465,8464,1,7733,7732,7032,7030,7028,7026,7024,7022,7020,7018,7016,7014,7012,7010,7008,1,7006,7004,7002,7000,6998,6996,6994,6992,6990,6988,6986,6984,6982,6980,6978,1,6976,6974,6972,6970,6968,6966,6964,6962,6960,6958,6956,6954,6952,6950,6948,1,6946,6944,6942,6940,6938,6936,6934,6932,6930,6928,6926,6924,6922,6920,6918,1,6916,6914,6912,6910,6908,6906,6904,6902,6900,6898,6896,6894,6892,6890,6888,1,6886,6884,6882,6880,6878,6876,6874,6872,6870,6868,6866,6862,6863,7546,7547,1,8262,8263,9010,9011,9790,9791,10602,10603,11446,11447,12322,12323,13230,13231,14170,1,14171,15142,15143,16146,16147,17182,17183,18250,18251,19350,19351, + 19743,19742,18627,18626,17543,17542,16491,16490,15471,15470,14483,0,14482,13527,13526,12603,12602,11711,11710,10851,10850,10023,10022,9227,9226,8463,8462,0,7731,7730,7033,7031,7029,7027,7025,7023,7021,7019,7017,7015,7013,7011,7009,0,7007,7005,7003,7001,6999,6997,6995,6993,6991,6989,6987,6985,6983,6981,6979,0,6977,6975,6973,6971,6969,6967,6965,6963,6961,6959,6957,6955,6953,6951,6949,0,6947,6945,6943,6941,6939,6937,6935,6933,6931,6929,6927,6925,6923,6921,6919,0,6917,6915,6913,6911,6909,6907,6905,6903,6901,6899,6897,6895,6893,6891,6889,0,6887,6885,6883,6881,6879,6877,6875,6873,6871,6869,6867,6864,6865,7548,7549,0,8264,8265,9012,9013,9792,9793,10604,10605,11448,11449,12324,12325,13232,13233,14172,0,14173,15144,15145,16148,16149,17184,17185,18252,18253,19352,19353, + 19741,19740,18625,18624,17541,17540,16489,16488,15469,15468,14481,1,14480,13525,13524,12601,12600,11709,11708,10849,10848,10021,10020,9225,9224,8461,8460,1,7728,7726,7724,7722,7720,7718,7716,7714,7712,7710,7708,7706,7704,7702,7700,1,7698,7696,7694,7692,7690,7688,7686,7684,7682,7680,7678,7676,7674,7672,7670,1,7668,7666,7664,7662,7660,7658,7656,7654,7652,7650,7648,7646,7644,7642,7640,1,7638,7636,7634,7632,7630,7628,7626,7624,7622,7620,7618,7616,7614,7612,7610,1,7608,7606,7604,7602,7600,7598,7596,7594,7592,7590,7588,7586,7584,7582,7580,1,7578,7576,7574,7572,7570,7568,7566,7564,7562,7560,7558,7556,7554,7550,7551,1,8266,8267,9014,9015,9794,9795,10606,10607,11450,11451,12326,12327,13234,13235,14174,1,14175,15146,15147,16150,16151,17186,17187,18254,18255,19354,19355, + 19739,19738,18623,18622,17539,17538,16487,16486,15467,15466,14479,0,14478,13523,13522,12599,12598,11707,11706,10847,10846,10019,10018,9223,9222,8459,8458,0,7729,7727,7725,7723,7721,7719,7717,7715,7713,7711,7709,7707,7705,7703,7701,0,7699,7697,7695,7693,7691,7689,7687,7685,7683,7681,7679,7677,7675,7673,7671,0,7669,7667,7665,7663,7661,7659,7657,7655,7653,7651,7649,7647,7645,7643,7641,0,7639,7637,7635,7633,7631,7629,7627,7625,7623,7621,7619,7617,7615,7613,7611,0,7609,7607,7605,7603,7601,7599,7597,7595,7593,7591,7589,7587,7585,7583,7581,0,7579,7577,7575,7573,7571,7569,7567,7565,7563,7561,7559,7557,7555,7552,7553,0,8268,8269,9016,9017,9796,9797,10608,10609,11452,11453,12328,12329,13236,13237,14176,0,14177,15148,15149,16152,16153,17188,17189,18256,18257,19356,19357, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19737,19736,18621,18620,17537,17536,16485,16484,15465,15464,14477,0,14476,13521,13520,12597,12596,11705,11704,10845,10844,10017,10016,9221,9220,8456,8454,0,8452,8450,8448,8446,8444,8442,8440,8438,8436,8434,8432,8430,8428,8426,8424,0,8422,8420,8418,8416,8414,8412,8410,8408,8406,8404,8402,8400,8398,8396,8394,0,8392,8390,8388,8386,8384,8382,8380,8378,8376,8374,8372,8370,8368,8366,8364,0,8362,8360,8358,8356,8354,8352,8350,8348,8346,8344,8342,8340,8338,8336,8334,0,8332,8330,8328,8326,8324,8322,8320,8318,8316,8314,8312,8310,8308,8306,8304,0,8302,8300,8298,8296,8294,8292,8290,8288,8286,8284,8282,8280,8278,8276,8274,0,8270,8271,9018,9019,9798,9799,10610,10611,11454,11455,12330,12331,13238,13239,14178,0,14179,15150,15151,16154,16155,17190,17191,18258,18259,19358,19359, + 19735,19734,18619,18618,17535,17534,16483,16482,15463,15462,14475,1,14474,13519,13518,12595,12594,11703,11702,10843,10842,10015,10014,9219,9218,8457,8455,1,8453,8451,8449,8447,8445,8443,8441,8439,8437,8435,8433,8431,8429,8427,8425,1,8423,8421,8419,8417,8415,8413,8411,8409,8407,8405,8403,8401,8399,8397,8395,1,8393,8391,8389,8387,8385,8383,8381,8379,8377,8375,8373,8371,8369,8367,8365,1,8363,8361,8359,8357,8355,8353,8351,8349,8347,8345,8343,8341,8339,8337,8335,1,8333,8331,8329,8327,8325,8323,8321,8319,8317,8315,8313,8311,8309,8307,8305,1,8303,8301,8299,8297,8295,8293,8291,8289,8287,8285,8283,8281,8279,8277,8275,1,8272,8273,9020,9021,9800,9801,10612,10613,11456,11457,12332,12333,13240,13241,14180,1,14181,15152,15153,16156,16157,17192,17193,18260,18261,19360,19361, + 19733,19732,18617,18616,17533,17532,16481,16480,15461,15460,14473,0,14472,13517,13516,12593,12592,11701,11700,10841,10840,10013,10012,9216,9214,9212,9210,0,9208,9206,9204,9202,9200,9198,9196,9194,9192,9190,9188,9186,9184,9182,9180,0,9178,9176,9174,9172,9170,9168,9166,9164,9162,9160,9158,9156,9154,9152,9150,0,9148,9146,9144,9142,9140,9138,9136,9134,9132,9130,9128,9126,9124,9122,9120,0,9118,9116,9114,9112,9110,9108,9106,9104,9102,9100,9098,9096,9094,9092,9090,0,9088,9086,9084,9082,9080,9078,9076,9074,9072,9070,9068,9066,9064,9062,9060,0,9058,9056,9054,9052,9050,9048,9046,9044,9042,9040,9038,9036,9034,9032,9030,0,9028,9026,9022,9023,9802,9803,10614,10615,11458,11459,12334,12335,13242,13243,14182,0,14183,15154,15155,16158,16159,17194,17195,18262,18263,19362,19363, + 19731,19730,18615,18614,17531,17530,16479,16478,15459,15458,14471,1,14470,13515,13514,12591,12590,11699,11698,10839,10838,10011,10010,9217,9215,9213,9211,1,9209,9207,9205,9203,9201,9199,9197,9195,9193,9191,9189,9187,9185,9183,9181,1,9179,9177,9175,9173,9171,9169,9167,9165,9163,9161,9159,9157,9155,9153,9151,1,9149,9147,9145,9143,9141,9139,9137,9135,9133,9131,9129,9127,9125,9123,9121,1,9119,9117,9115,9113,9111,9109,9107,9105,9103,9101,9099,9097,9095,9093,9091,1,9089,9087,9085,9083,9081,9079,9077,9075,9073,9071,9069,9067,9065,9063,9061,1,9059,9057,9055,9053,9051,9049,9047,9045,9043,9041,9039,9037,9035,9033,9031,1,9029,9027,9024,9025,9804,9805,10616,10617,11460,11461,12336,12337,13244,13245,14184,1,14185,15156,15157,16160,16161,17196,17197,18264,18265,19364,19365, + 19729,19728,18613,18612,17529,17528,16477,16476,15457,15456,14469,0,14468,13513,13512,12589,12588,11697,11696,10837,10836,10008,10006,10004,10002,10000,9998,0,9996,9994,9992,9990,9988,9986,9984,9982,9980,9978,9976,9974,9972,9970,9968,0,9966,9964,9962,9960,9958,9956,9954,9952,9950,9948,9946,9944,9942,9940,9938,0,9936,9934,9932,9930,9928,9926,9924,9922,9920,9918,9916,9914,9912,9910,9908,0,9906,9904,9902,9900,9898,9896,9894,9892,9890,9888,9886,9884,9882,9880,9878,0,9876,9874,9872,9870,9868,9866,9864,9862,9860,9858,9856,9854,9852,9850,9848,0,9846,9844,9842,9840,9838,9836,9834,9832,9830,9828,9826,9824,9822,9820,9818,0,9816,9814,9812,9810,9806,9807,10618,10619,11462,11463,12338,12339,13246,13247,14186,0,14187,15158,15159,16162,16163,17198,17199,18266,18267,19366,19367, + 19727,19726,18611,18610,17527,17526,16475,16474,15455,15454,14467,1,14466,13511,13510,12587,12586,11695,11694,10835,10834,10009,10007,10005,10003,10001,9999,1,9997,9995,9993,9991,9989,9987,9985,9983,9981,9979,9977,9975,9973,9971,9969,1,9967,9965,9963,9961,9959,9957,9955,9953,9951,9949,9947,9945,9943,9941,9939,1,9937,9935,9933,9931,9929,9927,9925,9923,9921,9919,9917,9915,9913,9911,9909,1,9907,9905,9903,9901,9899,9897,9895,9893,9891,9889,9887,9885,9883,9881,9879,1,9877,9875,9873,9871,9869,9867,9865,9863,9861,9859,9857,9855,9853,9851,9849,1,9847,9845,9843,9841,9839,9837,9835,9833,9831,9829,9827,9825,9823,9821,9819,1,9817,9815,9813,9811,9808,9809,10620,10621,11464,11465,12340,12341,13248,13249,14188,1,14189,15160,15161,16164,16165,17200,17201,18268,18269,19368,19369, + 19725,19724,18609,18608,17525,17524,16473,16472,15453,15452,14465,0,14464,13509,13508,12585,12584,11693,11692,10832,10830,10828,10826,10824,10822,10820,10818,0,10816,10814,10812,10810,10808,10806,10804,10802,10800,10798,10796,10794,10792,10790,10788,0,10786,10784,10782,10780,10778,10776,10774,10772,10770,10768,10766,10764,10762,10760,10758,0,10756,10754,10752,10750,10748,10746,10744,10742,10740,10738,10736,10734,10732,10730,10728,0,10726,10724,10722,10720,10718,10716,10714,10712,10710,10708,10706,10704,10702,10700,10698,0,10696,10694,10692,10690,10688,10686,10684,10682,10680,10678,10676,10674,10672,10670,10668,0,10666,10664,10662,10660,10658,10656,10654,10652,10650,10648,10646,10644,10642,10640,10638,0,10636,10634,10632,10630,10628,10626,10622,10623,11466,11467,12342,12343,13250,13251,14190,0,14191,15162,15163,16166,16167,17202,17203,18270,18271,19370,19371, + 19723,19722,18607,18606,17523,17522,16471,16470,15451,15450,14463,1,14462,13507,13506,12583,12582,11691,11690,10833,10831,10829,10827,10825,10823,10821,10819,1,10817,10815,10813,10811,10809,10807,10805,10803,10801,10799,10797,10795,10793,10791,10789,1,10787,10785,10783,10781,10779,10777,10775,10773,10771,10769,10767,10765,10763,10761,10759,1,10757,10755,10753,10751,10749,10747,10745,10743,10741,10739,10737,10735,10733,10731,10729,1,10727,10725,10723,10721,10719,10717,10715,10713,10711,10709,10707,10705,10703,10701,10699,1,10697,10695,10693,10691,10689,10687,10685,10683,10681,10679,10677,10675,10673,10671,10669,1,10667,10665,10663,10661,10659,10657,10655,10653,10651,10649,10647,10645,10643,10641,10639,1,10637,10635,10633,10631,10629,10627,10624,10625,11468,11469,12344,12345,13252,13253,14192,1,14193,15164,15165,16168,16169,17204,17205,18272,18273,19372,19373, + 19721,19720,18605,18604,17521,17520,16469,16468,15449,15448,14461,0,14460,13505,13504,12581,12580,11688,11686,11684,11682,11680,11678,11676,11674,11672,11670,0,11668,11666,11664,11662,11660,11658,11656,11654,11652,11650,11648,11646,11644,11642,11640,0,11638,11636,11634,11632,11630,11628,11626,11624,11622,11620,11618,11616,11614,11612,11610,0,11608,11606,11604,11602,11600,11598,11596,11594,11592,11590,11588,11586,11584,11582,11580,0,11578,11576,11574,11572,11570,11568,11566,11564,11562,11560,11558,11556,11554,11552,11550,0,11548,11546,11544,11542,11540,11538,11536,11534,11532,11530,11528,11526,11524,11522,11520,0,11518,11516,11514,11512,11510,11508,11506,11504,11502,11500,11498,11496,11494,11492,11490,0,11488,11486,11484,11482,11480,11478,11476,11474,11470,11471,12346,12347,13254,13255,14194,0,14195,15166,15167,16170,16171,17206,17207,18274,18275,19374,19375, + 19719,19718,18603,18602,17519,17518,16467,16466,15447,15446,14459,1,14458,13503,13502,12579,12578,11689,11687,11685,11683,11681,11679,11677,11675,11673,11671,1,11669,11667,11665,11663,11661,11659,11657,11655,11653,11651,11649,11647,11645,11643,11641,1,11639,11637,11635,11633,11631,11629,11627,11625,11623,11621,11619,11617,11615,11613,11611,1,11609,11607,11605,11603,11601,11599,11597,11595,11593,11591,11589,11587,11585,11583,11581,1,11579,11577,11575,11573,11571,11569,11567,11565,11563,11561,11559,11557,11555,11553,11551,1,11549,11547,11545,11543,11541,11539,11537,11535,11533,11531,11529,11527,11525,11523,11521,1,11519,11517,11515,11513,11511,11509,11507,11505,11503,11501,11499,11497,11495,11493,11491,1,11489,11487,11485,11483,11481,11479,11477,11475,11472,11473,12348,12349,13256,13257,14196,1,14197,15168,15169,16172,16173,17208,17209,18276,18277,19376,19377, + 19717,19716,18601,18600,17517,17516,16465,16464,15445,15444,14457,0,14456,13501,13500,12576,12574,12572,12570,12568,12566,12564,12562,12560,12558,12556,12554,0,12552,12550,12548,12546,12544,12542,12540,12538,12536,12534,12532,12530,12528,12526,12524,0,12522,12520,12518,12516,12514,12512,12510,12508,12506,12504,12502,12500,12498,12496,12494,0,12492,12490,12488,12486,12484,12482,12480,12478,12476,12474,12472,12470,12468,12466,12464,0,12462,12460,12458,12456,12454,12452,12450,12448,12446,12444,12442,12440,12438,12436,12434,0,12432,12430,12428,12426,12424,12422,12420,12418,12416,12414,12412,12410,12408,12406,12404,0,12402,12400,12398,12396,12394,12392,12390,12388,12386,12384,12382,12380,12378,12376,12374,0,12372,12370,12368,12366,12364,12362,12360,12358,12356,12354,12350,12351,13258,13259,14198,0,14199,15170,15171,16174,16175,17210,17211,18278,18279,19378,19379, + 19715,19714,18599,18598,17515,17514,16463,16462,15443,15442,14455,1,14454,13499,13498,12577,12575,12573,12571,12569,12567,12565,12563,12561,12559,12557,12555,1,12553,12551,12549,12547,12545,12543,12541,12539,12537,12535,12533,12531,12529,12527,12525,1,12523,12521,12519,12517,12515,12513,12511,12509,12507,12505,12503,12501,12499,12497,12495,1,12493,12491,12489,12487,12485,12483,12481,12479,12477,12475,12473,12471,12469,12467,12465,1,12463,12461,12459,12457,12455,12453,12451,12449,12447,12445,12443,12441,12439,12437,12435,1,12433,12431,12429,12427,12425,12423,12421,12419,12417,12415,12413,12411,12409,12407,12405,1,12403,12401,12399,12397,12395,12393,12391,12389,12387,12385,12383,12381,12379,12377,12375,1,12373,12371,12369,12367,12365,12363,12361,12359,12357,12355,12352,12353,13260,13261,14200,1,14201,15172,15173,16176,16177,17212,17213,18280,18281,19380,19381, + 19713,19712,18597,18596,17513,17512,16461,16460,15441,15440,14453,0,14452,13496,13494,13492,13490,13488,13486,13484,13482,13480,13478,13476,13474,13472,13470,0,13468,13466,13464,13462,13460,13458,13456,13454,13452,13450,13448,13446,13444,13442,13440,0,13438,13436,13434,13432,13430,13428,13426,13424,13422,13420,13418,13416,13414,13412,13410,0,13408,13406,13404,13402,13400,13398,13396,13394,13392,13390,13388,13386,13384,13382,13380,0,13378,13376,13374,13372,13370,13368,13366,13364,13362,13360,13358,13356,13354,13352,13350,0,13348,13346,13344,13342,13340,13338,13336,13334,13332,13330,13328,13326,13324,13322,13320,0,13318,13316,13314,13312,13310,13308,13306,13304,13302,13300,13298,13296,13294,13292,13290,0,13288,13286,13284,13282,13280,13278,13276,13274,13272,13270,13268,13266,13262,13263,14202,0,14203,15174,15175,16178,16179,17214,17215,18282,18283,19382,19383, + 19711,19710,18595,18594,17511,17510,16459,16458,15439,15438,14451,1,14450,13497,13495,13493,13491,13489,13487,13485,13483,13481,13479,13477,13475,13473,13471,1,13469,13467,13465,13463,13461,13459,13457,13455,13453,13451,13449,13447,13445,13443,13441,1,13439,13437,13435,13433,13431,13429,13427,13425,13423,13421,13419,13417,13415,13413,13411,1,13409,13407,13405,13403,13401,13399,13397,13395,13393,13391,13389,13387,13385,13383,13381,1,13379,13377,13375,13373,13371,13369,13367,13365,13363,13361,13359,13357,13355,13353,13351,1,13349,13347,13345,13343,13341,13339,13337,13335,13333,13331,13329,13327,13325,13323,13321,1,13319,13317,13315,13313,13311,13309,13307,13305,13303,13301,13299,13297,13295,13293,13291,1,13289,13287,13285,13283,13281,13279,13277,13275,13273,13271,13269,13267,13264,13265,14204,1,14205,15176,15177,16180,16181,17216,17217,18284,18285,19384,19385, + 19709,19708,18593,18592,17509,17508,16457,16456,15437,15436,14448,0,14446,14444,14442,14440,14438,14436,14434,14432,14430,14428,14426,14424,14422,14420,14418,0,14416,14414,14412,14410,14408,14406,14404,14402,14400,14398,14396,14394,14392,14390,14388,0,14386,14384,14382,14380,14378,14376,14374,14372,14370,14368,14366,14364,14362,14360,14358,0,14356,14354,14352,14350,14348,14346,14344,14342,14340,14338,14336,14334,14332,14330,14328,0,14326,14324,14322,14320,14318,14316,14314,14312,14310,14308,14306,14304,14302,14300,14298,0,14296,14294,14292,14290,14288,14286,14284,14282,14280,14278,14276,14274,14272,14270,14268,0,14266,14264,14262,14260,14258,14256,14254,14252,14250,14248,14246,14244,14242,14240,14238,0,14236,14234,14232,14230,14228,14226,14224,14222,14220,14218,14216,14214,14212,14210,14206,0,14207,15178,15179,16182,16183,17218,17219,18286,18287,19386,19387, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 19707,19706,18591,18590,17507,17506,16455,16454,15435,15434,14449,0,14447,14445,14443,14441,14439,14437,14435,14433,14431,14429,14427,14425,14423,14421,14419,0,14417,14415,14413,14411,14409,14407,14405,14403,14401,14399,14397,14395,14393,14391,14389,0,14387,14385,14383,14381,14379,14377,14375,14373,14371,14369,14367,14365,14363,14361,14359,0,14357,14355,14353,14351,14349,14347,14345,14343,14341,14339,14337,14335,14333,14331,14329,0,14327,14325,14323,14321,14319,14317,14315,14313,14311,14309,14307,14305,14303,14301,14299,0,14297,14295,14293,14291,14289,14287,14285,14283,14281,14279,14277,14275,14273,14271,14269,0,14267,14265,14263,14261,14259,14257,14255,14253,14251,14249,14247,14245,14243,14241,14239,0,14237,14235,14233,14231,14229,14227,14225,14223,14221,14219,14217,14215,14213,14211,14208,0,14209,15180,15181,16184,16185,17220,17221,18288,18289,19388,19389, + 19705,19704,18589,18588,17505,17504,16453,16452,15432,15430,15428,1,15426,15424,15422,15420,15418,15416,15414,15412,15410,15408,15406,15404,15402,15400,15398,1,15396,15394,15392,15390,15388,15386,15384,15382,15380,15378,15376,15374,15372,15370,15368,1,15366,15364,15362,15360,15358,15356,15354,15352,15350,15348,15346,15344,15342,15340,15338,1,15336,15334,15332,15330,15328,15326,15324,15322,15320,15318,15316,15314,15312,15310,15308,1,15306,15304,15302,15300,15298,15296,15294,15292,15290,15288,15286,15284,15282,15280,15278,1,15276,15274,15272,15270,15268,15266,15264,15262,15260,15258,15256,15254,15252,15250,15248,1,15246,15244,15242,15240,15238,15236,15234,15232,15230,15228,15226,15224,15222,15220,15218,1,15216,15214,15212,15210,15208,15206,15204,15202,15200,15198,15196,15194,15192,15190,15188,1,15186,15182,15183,16186,16187,17222,17223,18290,18291,19390,19391, + 19703,19702,18587,18586,17503,17502,16451,16450,15433,15431,15429,0,15427,15425,15423,15421,15419,15417,15415,15413,15411,15409,15407,15405,15403,15401,15399,0,15397,15395,15393,15391,15389,15387,15385,15383,15381,15379,15377,15375,15373,15371,15369,0,15367,15365,15363,15361,15359,15357,15355,15353,15351,15349,15347,15345,15343,15341,15339,0,15337,15335,15333,15331,15329,15327,15325,15323,15321,15319,15317,15315,15313,15311,15309,0,15307,15305,15303,15301,15299,15297,15295,15293,15291,15289,15287,15285,15283,15281,15279,0,15277,15275,15273,15271,15269,15267,15265,15263,15261,15259,15257,15255,15253,15251,15249,0,15247,15245,15243,15241,15239,15237,15235,15233,15231,15229,15227,15225,15223,15221,15219,0,15217,15215,15213,15211,15209,15207,15205,15203,15201,15199,15197,15195,15193,15191,15189,0,15187,15184,15185,16188,16189,17224,17225,18292,18293,19392,19393, + 19701,19700,18585,18584,17501,17500,16448,16446,16444,16442,16440,1,16438,16436,16434,16432,16430,16428,16426,16424,16422,16420,16418,16416,16414,16412,16410,1,16408,16406,16404,16402,16400,16398,16396,16394,16392,16390,16388,16386,16384,16382,16380,1,16378,16376,16374,16372,16370,16368,16366,16364,16362,16360,16358,16356,16354,16352,16350,1,16348,16346,16344,16342,16340,16338,16336,16334,16332,16330,16328,16326,16324,16322,16320,1,16318,16316,16314,16312,16310,16308,16306,16304,16302,16300,16298,16296,16294,16292,16290,1,16288,16286,16284,16282,16280,16278,16276,16274,16272,16270,16268,16266,16264,16262,16260,1,16258,16256,16254,16252,16250,16248,16246,16244,16242,16240,16238,16236,16234,16232,16230,1,16228,16226,16224,16222,16220,16218,16216,16214,16212,16210,16208,16206,16204,16202,16200,1,16198,16196,16194,16190,16191,17226,17227,18294,18295,19394,19395, + 19699,19698,18583,18582,17499,17498,16449,16447,16445,16443,16441,0,16439,16437,16435,16433,16431,16429,16427,16425,16423,16421,16419,16417,16415,16413,16411,0,16409,16407,16405,16403,16401,16399,16397,16395,16393,16391,16389,16387,16385,16383,16381,0,16379,16377,16375,16373,16371,16369,16367,16365,16363,16361,16359,16357,16355,16353,16351,0,16349,16347,16345,16343,16341,16339,16337,16335,16333,16331,16329,16327,16325,16323,16321,0,16319,16317,16315,16313,16311,16309,16307,16305,16303,16301,16299,16297,16295,16293,16291,0,16289,16287,16285,16283,16281,16279,16277,16275,16273,16271,16269,16267,16265,16263,16261,0,16259,16257,16255,16253,16251,16249,16247,16245,16243,16241,16239,16237,16235,16233,16231,0,16229,16227,16225,16223,16221,16219,16217,16215,16213,16211,16209,16207,16205,16203,16201,0,16199,16197,16195,16192,16193,17228,17229,18296,18297,19396,19397, + 19697,19696,18581,18580,17496,17494,17492,17490,17488,17486,17484,1,17482,17480,17478,17476,17474,17472,17470,17468,17466,17464,17462,17460,17458,17456,17454,1,17452,17450,17448,17446,17444,17442,17440,17438,17436,17434,17432,17430,17428,17426,17424,1,17422,17420,17418,17416,17414,17412,17410,17408,17406,17404,17402,17400,17398,17396,17394,1,17392,17390,17388,17386,17384,17382,17380,17378,17376,17374,17372,17370,17368,17366,17364,1,17362,17360,17358,17356,17354,17352,17350,17348,17346,17344,17342,17340,17338,17336,17334,1,17332,17330,17328,17326,17324,17322,17320,17318,17316,17314,17312,17310,17308,17306,17304,1,17302,17300,17298,17296,17294,17292,17290,17288,17286,17284,17282,17280,17278,17276,17274,1,17272,17270,17268,17266,17264,17262,17260,17258,17256,17254,17252,17250,17248,17246,17244,1,17242,17240,17238,17236,17234,17230,17231,18298,18299,19398,19399, + 19695,19694,18579,18578,17497,17495,17493,17491,17489,17487,17485,0,17483,17481,17479,17477,17475,17473,17471,17469,17467,17465,17463,17461,17459,17457,17455,0,17453,17451,17449,17447,17445,17443,17441,17439,17437,17435,17433,17431,17429,17427,17425,0,17423,17421,17419,17417,17415,17413,17411,17409,17407,17405,17403,17401,17399,17397,17395,0,17393,17391,17389,17387,17385,17383,17381,17379,17377,17375,17373,17371,17369,17367,17365,0,17363,17361,17359,17357,17355,17353,17351,17349,17347,17345,17343,17341,17339,17337,17335,0,17333,17331,17329,17327,17325,17323,17321,17319,17317,17315,17313,17311,17309,17307,17305,0,17303,17301,17299,17297,17295,17293,17291,17289,17287,17285,17283,17281,17279,17277,17275,0,17273,17271,17269,17267,17265,17263,17261,17259,17257,17255,17253,17251,17249,17247,17245,0,17243,17241,17239,17237,17235,17232,17233,18300,18301,19400,19401, + 19693,19692,18576,18574,18572,18570,18568,18566,18564,18562,18560,1,18558,18556,18554,18552,18550,18548,18546,18544,18542,18540,18538,18536,18534,18532,18530,1,18528,18526,18524,18522,18520,18518,18516,18514,18512,18510,18508,18506,18504,18502,18500,1,18498,18496,18494,18492,18490,18488,18486,18484,18482,18480,18478,18476,18474,18472,18470,1,18468,18466,18464,18462,18460,18458,18456,18454,18452,18450,18448,18446,18444,18442,18440,1,18438,18436,18434,18432,18430,18428,18426,18424,18422,18420,18418,18416,18414,18412,18410,1,18408,18406,18404,18402,18400,18398,18396,18394,18392,18390,18388,18386,18384,18382,18380,1,18378,18376,18374,18372,18370,18368,18366,18364,18362,18360,18358,18356,18354,18352,18350,1,18348,18346,18344,18342,18340,18338,18336,18334,18332,18330,18328,18326,18324,18322,18320,1,18318,18316,18314,18312,18310,18308,18306,18302,18303,19402,19403, + 19691,19690,18577,18575,18573,18571,18569,18567,18565,18563,18561,0,18559,18557,18555,18553,18551,18549,18547,18545,18543,18541,18539,18537,18535,18533,18531,0,18529,18527,18525,18523,18521,18519,18517,18515,18513,18511,18509,18507,18505,18503,18501,0,18499,18497,18495,18493,18491,18489,18487,18485,18483,18481,18479,18477,18475,18473,18471,0,18469,18467,18465,18463,18461,18459,18457,18455,18453,18451,18449,18447,18445,18443,18441,0,18439,18437,18435,18433,18431,18429,18427,18425,18423,18421,18419,18417,18415,18413,18411,0,18409,18407,18405,18403,18401,18399,18397,18395,18393,18391,18389,18387,18385,18383,18381,0,18379,18377,18375,18373,18371,18369,18367,18365,18363,18361,18359,18357,18355,18353,18351,0,18349,18347,18345,18343,18341,18339,18337,18335,18333,18331,18329,18327,18325,18323,18321,0,18319,18317,18315,18313,18311,18309,18307,18304,18305,19404,19405, + 19688,19686,19684,19682,19680,19678,19676,19674,19672,19670,19668,1,19666,19664,19662,19660,19658,19656,19654,19652,19650,19648,19646,19644,19642,19640,19638,1,19636,19634,19632,19630,19628,19626,19624,19622,19620,19618,19616,19614,19612,19610,19608,1,19606,19604,19602,19600,19598,19596,19594,19592,19590,19588,19586,19584,19582,19580,19578,1,19576,19574,19572,19570,19568,19566,19564,19562,19560,19558,19556,19554,19552,19550,19548,1,19546,19544,19542,19540,19538,19536,19534,19532,19530,19528,19526,19524,19522,19520,19518,1,19516,19514,19512,19510,19508,19506,19504,19502,19500,19498,19496,19494,19492,19490,19488,1,19486,19484,19482,19480,19478,19476,19474,19472,19470,19468,19466,19464,19462,19460,19458,1,19456,19454,19452,19450,19448,19446,19444,19442,19440,19438,19436,19434,19432,19430,19428,1,19426,19424,19422,19420,19418,19416,19414,19412,19410,19406,19407, + 19689,19687,19685,19683,19681,19679,19677,19675,19673,19671,19669,0,19667,19665,19663,19661,19659,19657,19655,19653,19651,19649,19647,19645,19643,19641,19639,0,19637,19635,19633,19631,19629,19627,19625,19623,19621,19619,19617,19615,19613,19611,19609,0,19607,19605,19603,19601,19599,19597,19595,19593,19591,19589,19587,19585,19583,19581,19579,0,19577,19575,19573,19571,19569,19567,19565,19563,19561,19559,19557,19555,19553,19551,19549,0,19547,19545,19543,19541,19539,19537,19535,19533,19531,19529,19527,19525,19523,19521,19519,0,19517,19515,19513,19511,19509,19507,19505,19503,19501,19499,19497,19495,19493,19491,19489,0,19487,19485,19483,19481,19479,19477,19475,19473,19471,19469,19467,19465,19463,19461,19459,0,19457,19455,19453,19451,19449,19447,19445,19443,19441,19439,19437,19435,19433,19431,19429,0,19427,19425,19423,19421,19419,19417,19415,19413,19411,19408,19409 +}; + +static int CompactAztecMap[] = { /* 27 x 27 data grid */ + 609,608,411,413,415,417,419,421,423,425,427,429,431,433,435,437,439,441,443,445,447,449,451,453,455,457,459, + 607,606,410,412,414,416,418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,454,456,458, + 605,604,409,408,243,245,247,249,251,253,255,257,259,261,263,265,267,269,271,273,275,277,279,281,283,460,461, + 603,602,407,406,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,462,463, + 601,600,405,404,241,240,107,109,111,113,115,117,119,121,123,125,127,129,131,133,135,137,139,284,285,464,465, + 599,598,403,402,239,238,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,286,287,466,467, + 597,596,401,400,237,236,105,104,3,5,7,9,11,13,15,17,19,21,23,25,27,140,141,288,289,468,469, + 595,594,399,398,235,234,103,102,2,4,6,8,10,12,14,16,18,20,22,24,26,142,143,290,291,470,471, + 593,592,397,396,233,232,101,100,1,1,2000,2001,2002,2003,2004,2005,2006,0,1,28,29,144,145,292,293,472,473, + 591,590,395,394,231,230,99,98,1,1,1,1,1,1,1,1,1,1,1,30,31,146,147,294,295,474,475, + 589,588,393,392,229,228,97,96,2027,1,0,0,0,0,0,0,0,1,2007,32,33,148,149,296,297,476,477, + 587,586,391,390,227,226,95,94,2026,1,0,1,1,1,1,1,0,1,2008,34,35,150,151,298,299,478,479, + 585,584,389,388,225,224,93,92,2025,1,0,1,0,0,0,1,0,1,2009,36,37,152,153,300,301,480,481, + 583,582,387,386,223,222,91,90,2024,1,0,1,0,1,0,1,0,1,2010,38,39,154,155,302,303,482,483, + 581,580,385,384,221,220,89,88,2023,1,0,1,0,0,0,1,0,1,2011,40,41,156,157,304,305,484,485, + 579,578,383,382,219,218,87,86,2022,1,0,1,1,1,1,1,0,1,2012,42,43,158,159,306,307,486,487, + 577,576,381,380,217,216,85,84,2021,1,0,0,0,0,0,0,0,1,2013,44,45,160,161,308,309,488,489, + 575,574,379,378,215,214,83,82,0,1,1,1,1,1,1,1,1,1,1,46,47,162,163,310,311,490,491, + 573,572,377,376,213,212,81,80,0,0,2020,2019,2018,2017,2016,2015,2014,0,0,48,49,164,165,312,313,492,493, + 571,570,375,374,211,210,78,76,74,72,70,68,66,64,62,60,58,56,54,50,51,166,167,314,315,494,495, + 569,568,373,372,209,208,79,77,75,73,71,69,67,65,63,61,59,57,55,52,53,168,169,316,317,496,497, + 567,566,371,370,206,204,202,200,198,196,194,192,190,188,186,184,182,180,178,176,174,170,171,318,319,498,499, + 565,564,369,368,207,205,203,201,199,197,195,193,191,189,187,185,183,181,179,177,175,172,173,320,321,500,501, + 563,562,366,364,362,360,358,356,354,352,350,348,346,344,342,340,338,336,334,332,330,328,326,322,323,502,503, + 561,560,367,365,363,361,359,357,355,353,351,349,347,345,343,341,339,337,335,333,331,329,327,324,325,504,505, + 558,556,554,552,550,548,546,544,542,540,538,536,534,532,530,528,526,524,522,520,518,516,514,512,510,506,507, + 559,557,555,553,551,549,547,545,543,541,539,537,535,533,531,529,527,525,523,521,519,517,515,513,511,508,509 +}; + +int AztecCodeSet[128] = { /* From Table 2 */ + 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 12, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 4, 4, 4, 4, 4, 23, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 24, 8, 24, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, + 8, 8, 8, 8, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 8, 4, 4, 4, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 8, 4, 8, 4, 4 +}; + +int AztecSymbolChar[128] = { /* From Table 2 */ + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 300, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 1, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 301, 18, 302, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 22, + 23, 24, 25, 26, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 21, 28, 22, 23, 24, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 29, 25, 30, 26, 27 +}; + +/* Problem characters are: + 300: Carriage Return (ASCII 13) + 301: Comma (ASCII 44) + 302: Full Stop (ASCII 46) +*/ + +static char *hexbit[32] = {"00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", + "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", + "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" +}; + +static char *pentbit[16] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", + "1010", "1011", "1100", "1101", "1110", "1111" +}; + +static char *tribit[8] = {"000", "001", "010", "011", "100", "101", "110", "111"}; + +static int AztecSizes[32] = { /* Codewords per symbol */ + 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, + 864, 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664 +}; + +static int AztecCompactSizes[4] = { 17, 40, 51, 76 }; + +static int Aztec10DataSizes[32] = { /* Data bits per symbol maximum with 10% error correction */ + 96, 246, 408, 616, 840, 1104, 1392, 1704, 2040, 2420, 2820, 3250, 3720, 4200, 4730, + 5270, 5840, 6450, 7080, 7750, 8430, 9150, 9900, 10680, 11484, 12324, 13188, 14076, + 15000, 15948, 16920, 17940 +}; + +static int Aztec23DataSizes[32] = { /* Data bits per symbol maximum with 23% error correction */ + 84, 204, 352, 520, 720, 944, 1184, 1456, 1750, 2070, 2410, 2780, 3180, 3590, 4040, + 4500, 5000, 5520, 6060, 6630, 7210, 7830, 8472, 9132, 9816, 10536, 11280, 12036, + 12828, 13644, 14472, 15348 +}; + +static int Aztec36DataSizes[32] = { /* Data bits per symbol maximum with 36% error correction */ + 66, 168, 288, 432, 592, 776, 984, 1208, 1450, 1720, 2000, 2300, 2640, 2980, 3350, + 3740, 4150, 4580, 5030, 5500, 5990, 6500, 7032, 7584, 8160, 8760, 9372, 9996, 10656, + 11340, 12024, 12744 +}; + +static int Aztec50DataSizes[32] = { /* Data bits per symbol maximum with 50% error correction */ + 48, 126, 216, 328, 456, 600, 760, 936, 1120, 1330, 1550, 1790, 2050, 2320, 2610, + 2910, 3230, 3570, 3920, 4290, 4670, 5070, 5484, 5916, 6360, 6828, 7308, 7800, 8316, + 8844, 9384, 9948 +}; + +static int AztecCompact10DataSizes [4] = { 78, 198, 336, 520 }; +static int AztecCompact23DataSizes [4] = { 66, 168, 288, 440 }; +static int AztecCompact36DataSizes [4] = { 48, 138, 232, 360 }; +static int AztecCompact50DataSizes [4] = { 36, 102, 176, 280 }; + +static int AztecOffset[32] = { + 66, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 25, 23, 21, + 19, 17, 15, 13, 10, 8, 6, 4, 2, 0 +}; + +static int AztecCompactOffset[4] = { 6, 4, 2, 0 }; diff --git a/backend/code.c b/backend/code.c new file mode 100644 index 00000000..5135020a --- /dev/null +++ b/backend/code.c @@ -0,0 +1,542 @@ +/* code.c - Handles Code 11, 39, 39+ and 93 */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* In version 0.5 this file was 1,553 lines long! */ + +#include +#include +#include +#include "common.h" + +#define SODIUM "0123456789-" +#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd" + +static char *C11Table[11] = {"111121", "211121", "121121", "221111", "112121", "212111", "122111", + "111221", "211211", "211111", "112111"}; + + +/* Code 39 tables checked against ISO/IEC 16388:2007 */ + +/* Incorporates Table A1 */ + +static char *C39Table[43] = { "1112212111", "2112111121", "1122111121", "2122111111", "1112211121", + "2112211111", "1122211111", "1112112121", "2112112111", "1122112111", "2111121121", + "1121121121", "2121121111", "1111221121", "2111221111", "1121221111", "1111122121", + "2111122111", "1121122111", "1111222111", "2111111221", "1121111221", "2121111211", + "1111211221", "2111211211", "1121211211", "1111112221", "2111112211", "1121112211", + "1111212211", "2211111121", "1221111121", "2221111111", "1211211121", "2211211111", + "1221211111", "1211112121", "2211112111", "1221112111", "1212121111", "1212111211", + "1211121211", "1112121211"}; +/* Code 39 character assignments (Table 1) */ + +static char *EC39Ctrl[128] = {"%U", "$A", "$B", "$C", "$D", "$E", "$F", "$G", "$H", "$I", "$J", "$K", + "$L", "$M", "$N", "$O", "$P", "$Q", "$R", "$S", "$T", "$U", "$V", "$W", "$X", "$Y", "$Z", + "%A", "%B", "%C", "%D", "%E", " ", "/A", "/B", "/C", "/D", "/E", "/F", "/G", "/H", "/I", "/J", + "/K", "/L", "-", ".", "/O", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/Z", "%F", + "%G", "%H", "%I", "%J", "%V", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%K", "%L", "%M", "%N", "%O", + "%W", "+A", "+B", "+C", "+D", "+E", "+F", "+G", "+H", "+I", "+J", "+K", "+L", "+M", "+N", "+O", + "+P", "+Q", "+R", "+S", "+T", "+U", "+V", "+W", "+X", "+Y", "+Z", "%P", "%Q", "%R", "%S", "%T"}; +/* Encoding the full ASCII character set in Code 39 (Table A2) */ + +static char *C93Ctrl[128] = {"bU", "aA", "aB", "aC", "aD", "aE", "aF", "aG", "aH", "aI", "aJ", "aK", + "aL", "aM", "aN", "aO", "aP", "aQ", "aR", "aS", "aT", "aU", "aV", "aW", "aX", "aY", "aZ", + "bA", "bB", "bC", "bD", "bE", " ", "cA", "cB", "cC", "cD", "cE", "cF", "cG", "cH", "cI", "cJ", + "cK", "cL", "cM", "cN", "cO", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "cZ", "bF", + "bG", "bH", "bI", "bJ", "bV", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bK", "bL", "bM", "bN", "bO", + "bW", "dA", "dB", "dC", "dD", "dE", "dF", "dG", "dH", "dI", "dJ", "dK", "dL", "dM", "dN", "dO", + "dP", "dQ", "dR", "dS", "dT", "dU", "dV", "dW", "dX", "dY", "dZ", "bP", "bQ", "bR", "bS", "bT"}; + +static char *C93Table[47] = {"131112", "111213", "111312", "111411", "121113", "121212", "121311", + "111114", "131211", "141111", "211113", "211212", "211311", "221112", "221211", "231111", + "112113", "112212", "112311", "122112", "132111", "111123", "111222", "111321", "121122", + "131121", "212112", "212211", "211122", "211221", "221121", "222111", "112122", "112221", + "122121", "123111", "121131", "311112", "311211", "321111", "112131", "113121", "211131", + "121221", "312111", "311121", "122211"}; + +/* Global Variables for Channel Code */ +int S[11], B[11]; +long value; +long target_value; +char pattern[30]; + +/* Function Prototypes */ +void NextS(int Chan, int i, int MaxS, int MaxB); +void NextB(int Chan, int i, int MaxB, int MaxS); + +/* *********************** CODE 11 ******************** */ + +int code_11(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 11 */ + + unsigned int i; + int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count; + int weight[128], error_number; + char dest[1024]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/ + char checkstr[3]; + + error_number = 0; + + if(length > 121) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(SODIUM, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + c_weight = 1; + c_count = 0; + k_weight = 1; + k_count = 0; + + /* start character */ + strcpy(dest, "112211"); + + /* Draw main body of barcode */ + for(i = 0; i < length; i++) { + lookup(SODIUM, C11Table, source[i], dest); + if(source[i] == '-') + weight[i] = 10; + else + weight[i] = ctoi(source[i]); + } + + /* Calculate C checksum */ + for(h = length - 1; h >= 0; h--) { + c_count += (c_weight * weight[h]); + c_weight++; + + if(c_weight > 10) { + c_weight = 1; + } + } + c_digit = c_count % 11; + + weight[length] = c_digit; + + /* Calculate K checksum */ + for(h = length; h >= 0; h--) { + k_count += (k_weight * weight[h]); + k_weight++; + + if(k_weight > 9) { + k_weight = 1; + } + } + k_digit = k_count % 11; + + checkstr[0] = itoc(c_digit); + checkstr[1] = itoc(k_digit); + if(checkstr[0] == 'A') { checkstr[0] = '-'; } + if(checkstr[1] == 'A') { checkstr[1] = '-'; } + checkstr[2] = '\0'; + lookup(SODIUM, C11Table, checkstr[0], dest); + lookup(SODIUM, C11Table, checkstr[1], dest); + + /* Stop character */ + concat (dest, "11221"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + uconcat(symbol->text, (unsigned char*)checkstr); + return error_number; +} + +int c39(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 39 */ + unsigned int i; + unsigned int counter; + char check_digit; + int error_number; + char dest[775]; + char localstr[2] = { 0 }; + + error_number = 0; + counter = 0; + + if((symbol->option_2 < 0) || (symbol->option_2 > 1)) { + symbol->option_2 = 0; + } + + if((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } else if(length > 74) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(SILVER , source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* Start character */ + strcpy(dest, "1211212111"); + + for(i = 0; i < length; i++) { + lookup(SILVER, C39Table, source[i], dest); + counter += posn(SILVER, source[i]); + } + + if((symbol->symbology == BARCODE_LOGMARS) || (symbol->option_2 == 1)) { + + counter = counter % 43; + if(counter < 10) { + check_digit = itoc(counter); + } else { + if(counter < 36) { + check_digit = (counter - 10) + 'A'; + } else { + switch(counter) { + case 36: check_digit = '-'; break; + case 37: check_digit = '.'; break; + case 38: check_digit = ' '; break; + case 39: check_digit = '$'; break; + case 40: check_digit = '/'; break; + case 41: check_digit = '+'; break; + case 42: check_digit = 37; break; + default: check_digit = ' '; break; /* Keep compiler happy */ + } + } + } + lookup(SILVER, C39Table, check_digit, dest); + + /* Display a space check digit as _, otherwise it looks like an error */ + if(check_digit == ' ') { + check_digit = '_'; + } + + localstr[0] = check_digit; + localstr[1] = '\0'; + } + + /* Stop character */ + concat (dest, "121121211"); + + if((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) { + /* LOGMARS uses wider 'wide' bars than normal Code 39 */ + counter = strlen(dest); + for(i = 0; i < counter; i++) { + if(dest[i] == '2') { + dest[i] = '3'; + } + } + } + + expand(symbol, dest); + + if(symbol->symbology == BARCODE_CODE39) { + ustrcpy(symbol->text, (unsigned char*)"*"); + uconcat(symbol->text, source); + uconcat(symbol->text, (unsigned char*)localstr); + uconcat(symbol->text, (unsigned char*)"*"); + } else { + ustrcpy(symbol->text, source); + uconcat(symbol->text, (unsigned char*)localstr); + } + return error_number; +} + +int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Pharmazentral Nummer (PZN) */ + + int i, error_number, zeroes; + unsigned int count, check_digit; + char localstr[10]; + + error_number = 0; + + count = 0; + if(length > 6) { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + localstr[0] = '-'; + zeroes = 6 - length + 1; + for(i = 1; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *)source); + + for (i = 1; i < 7; i++) { + count += (i + 1) * ctoi(localstr[i]); + } + + check_digit = count%11; + if (check_digit == 11) { check_digit = 0; } + localstr[7] = itoc(check_digit); + localstr[8] = '\0'; + if(localstr[7] == 'A') { + strcpy(symbol->errtxt, "Invalid PZN Data"); + return ERROR_INVALID_DATA; + } + error_number = c39(symbol, (unsigned char *)localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char *)"PZN"); + uconcat(symbol->text, (unsigned char *)localstr); + return error_number; +} + + +/* ************** EXTENDED CODE 39 *************** */ + +int ec39(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Extended Code 39 - ISO/IEC 16388:2007 Annex A */ + + unsigned char buffer[150] = { 0 }; + unsigned int i; + int error_number; + + error_number = 0; + + if(length > 74) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Creates a buffer string and places control characters into it */ + for(i = 0; i < length; i++) { + if(source[i] > 127) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + concat((char*)buffer, EC39Ctrl[source[i]]); + } + + /* Then sends the buffer to the C39 function */ + error_number = c39(symbol, buffer, ustrlen(buffer)); + + for(i = 0; i < length; i++) + symbol->text[i] = source[i] ? source[i] : ' '; + symbol->text[length] = '\0'; + + return error_number; +} + +/* ******************** CODE 93 ******************* */ + +int c93(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Code 93 is an advancement on Code 39 and the definition is a lot tighter */ + + /* SILVER includes the extra characters a, b, c and d to represent Code 93 specific + shift characters 1, 2, 3 and 4 respectively. These characters are never used by + c39() and ec39() */ + + int i; + int h, weight, c, k, values[128], error_number; + char buffer[220]; + char dest[670]; + char set_copy[] = SILVER; + + error_number = 0; + strcpy(buffer, ""); + + if(length > 107) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Message Content */ + for (i = 0; i < length; i++) { + if (source[i] > 127) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + concat(buffer, C93Ctrl[source[i]]); + symbol->text[i] = source[i] ? source[i] : ' '; + } + + /* Now we can check the true length of the barcode */ + h = strlen(buffer); + if (h > 107) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + for (i = 0; i < h; i++) { + values[i] = posn(SILVER, buffer[i]); + } + + /* Putting the data into dest[] is not done until after check digits are calculated */ + + /* Check digit C */ + c = 0; + weight = 1; + for (i = h - 1; i >= 0; i--) { + c += values[i] * weight; + weight++; + if (weight == 21) + weight = 1; + } + c = c % 47; + values[h] = c; + buffer[h] = set_copy[c]; + + /* Check digit K */ + k = 0; + weight = 1; + for (i = h; i >= 0; i--) { + k += values[i] * weight; + weight++; + if(weight == 16) + weight = 1; + } + k = k % 47; + buffer[++h] = set_copy[k]; + buffer[++h] = '\0'; + + /* Start character */ + strcpy(dest, "111141"); + + for(i = 0; i < h; i++) { + lookup(SILVER, C93Table, buffer[i], dest); + } + + /* Stop character */ + concat(dest, "1111411"); + expand(symbol, dest); + + symbol->text[length] = set_copy[c]; + symbol->text[length + 1] = set_copy[k]; + symbol->text[length + 2] = '\0'; + + return error_number; +} + +/* NextS() and NextB() are from ANSI/AIM BC12-1998 and are Copyright (c) AIM 1997 */ +/* Their are used here on the understanding that they form part of the specification + for Channel Code and therefore their use is permitted under the following terms + set out in that document: + + "It is the intent and understanding of AIM [t]hat the symbology presented in this + specification is entirely in the public domain and free of all use restrictions, + licenses and fees. AIM USA, its memer companies, or individual officers + assume no liability for the use of this document." */ + +void CheckCharacter() { + int i; + char part[3]; + + if(value == target_value) { + /* Target reached - save the generated pattern */ + strcpy(pattern, "11110"); + for(i = 0; i < 11; i++) { + part[0] = itoc(S[i]); + part[1] = itoc(B[i]); + part[2] = '\0'; + concat(pattern, part); + } + } +} + +void NextB(int Chan, int i, int MaxB, int MaxS) { + int b; + + b = (S[i]+B[i-1]+S[i-1]+B[i-2] > 4)? 1:2; + if (i < Chan+2) { + for (; b <= MaxB; b++) { + B[i] = b; + NextS(Chan,i+1,MaxS,MaxB+1-b); + } + } else if (b <= MaxB) { + B[i] = MaxB; + CheckCharacter(); + value++; + } +} + +void NextS(int Chan, int i, int MaxS, int MaxB) { + int s; + + for (s = (i 7) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + if((symbol->option_2 < 3) || (symbol->option_2 > 8)) { channels = 0; } else { channels = symbol->option_2; } + if(channels == 0) { channels = length + 1; } + if(channels == 2) { channels = 3; } + + for(i = 0; i < length; i++) { + target_value *= 10; + target_value += ctoi((char) source[i]); + } + + switch(channels) { + case 3: if(target_value > 26) { range = 1; } break; + case 4: if(target_value > 292) { range = 1; } break; + case 5: if(target_value > 3493) { range = 1; } break; + case 6: if(target_value > 44072) { range = 1; } break; + case 7: if(target_value > 576688) { range = 1; } break; + case 8: if(target_value > 7742862) { range = 1; } break; + } + if(range) { + strcpy(symbol->errtxt, "Value out of range"); + return ERROR_INVALID_DATA; + } + + for(i = 0; i < 11; i++) { B[i] = 0; S[i] = 0; } + + B[0] = S[1] = B[1] = S[2] = B[2] = 1; + value = 0; + NextS(channels,3,channels,channels); + + zeroes = channels - 1 - length; + memset(hrt, '0', zeroes); + strcpy(hrt + zeroes, (char *)source); + ustrcpy(symbol->text, (unsigned char *)hrt); + + expand(symbol, pattern); + + return error_number; +} diff --git a/backend/code1.c b/backend/code1.c new file mode 100644 index 00000000..506ade6d --- /dev/null +++ b/backend/code1.c @@ -0,0 +1,1536 @@ +/* code1.c - USS Code One */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 "common.h" +#include "code1.h" +#include "reedsol.h" +#include "large.h" +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + +void horiz(struct zint_symbol *symbol, int row_no, int full) +{ + int i; + + if(full) { + for(i = 0; i < symbol->width; i++) { + set_module(symbol, row_no, i); + } + } else { + for(i = 1; i < symbol->width - 1; i++) { + set_module(symbol, row_no, i); + } + } +} + +void central_finder(struct zint_symbol *symbol, int start_row, int row_count, int full_rows) +{ + int i; + + for(i = 0; i < row_count; i++) { + if(i < full_rows) { + horiz(symbol, start_row + (i * 2), 1); + } else { + horiz(symbol, start_row + (i * 2), 0); + if(i != row_count - 1) { + set_module(symbol, start_row + (i * 2) + 1, 1); + set_module(symbol, start_row + (i * 2) + 1, symbol->width - 2); + } + } + } +} + +void vert(struct zint_symbol *symbol, int column, int height, int top) +{ + int i; + + if(top) { + for (i = 0; i < height; i++) { + set_module(symbol, i, column); + } + } else { + for (i = 0; i < height; i++) { + set_module(symbol, symbol->rows - i - 1, column); + } + } +} + +void spigot(struct zint_symbol *symbol, int row_no) +{ + int i; + + for(i = symbol->width - 1; i > 0; i--) { + if(module_is_set(symbol, row_no, i - 1)) { + set_module(symbol, row_no, i); + } + } +} + +int isedi(unsigned char input) +{ + int result = 0; + + if(input == 13) { result = 1; } + if(input == '*') { result = 1; } + if(input == '>') { result = 1; } + if(input == ' ') { result = 1; } + if((input >= '0') && (input <= '9')) { result = 1; } + if((input >= 'A') && (input <= 'Z')) { result = 1; } + + return result; +} + +int dq4bi(unsigned char source[], int sourcelen, int position) +{ + int i; + + for(i = position; isedi(source[position + i]) && ((position + i) < sourcelen); i++); + + if((position + i) == sourcelen) { + /* Reached end of input */ + return 0; + } + + if (source[position + i - 1] == 13) { return 1; } + if (source[position + i - 1] == '*') { return 1; } + if (source[position + i - 1] == '>') { return 1; } + + return 0; +} + +int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) +{ + float ascii_count, c40_count, text_count, edi_count, byte_count; + char reduced_char; + int done, best_scheme, best_count, sp; + + /* Step J */ + if(current_mode == C1_ASCII) { + ascii_count = 0.0; + c40_count = 1.0; + text_count = 1.0; + edi_count = 1.0; + byte_count = 2.0; + } else { + ascii_count = 1.0; + c40_count = 2.0; + text_count = 2.0; + edi_count = 2.0; + byte_count = 3.0; + } + + switch(current_mode) { + case C1_C40: c40_count = 0.0; break; + case C1_TEXT: text_count = 0.0; break; + case C1_BYTE: byte_count = 0.0; break; + case C1_EDI: edi_count = 0.0; break; + } + + for(sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { + + if(source[sp] <= 127) { reduced_char = source[sp]; } else { reduced_char = source[sp] - 127; } + + /* Step L */ + if((source[sp] >= '0') && (source[sp] <= '9')) { + ascii_count += 0.5; + } else { + ascii_count = froundup(ascii_count); + if(source[sp] > 127) { + ascii_count += 2.0; + } else { + ascii_count += 1.0; + } + } + + /* Step M */ + done = 0; + if(reduced_char == ' ') { c40_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= '0') && (reduced_char <= '9')) { c40_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= 'A') && (reduced_char <= 'Z')) { c40_count += (2.0 / 3.0); done = 1; } + if(source[sp] > 127) { c40_count += (4.0 / 3.0); } + if(done == 0) { c40_count += (4.0 / 3.0); } + + /* Step N */ + done = 0; + if(reduced_char == ' ') { text_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= '0') && (reduced_char <= '9')) { text_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= 'a') && (reduced_char <= 'z')) { text_count += (2.0 / 3.0); done = 1; } + if(source[sp] > 127) { text_count += (4.0 / 3.0); } + if(done == 0) { text_count += (4.0 / 3.0); } + + /* Step O */ + done = 0; + if(source[sp] == 13) { edi_count += (2.0 / 3.0); done = 1; } + if(source[sp] == '*') { edi_count += (2.0 / 3.0); done = 1; } + if(source[sp] == '>') { edi_count += (2.0 / 3.0); done = 1; } + if(source[sp] == ' ') { edi_count += (2.0 / 3.0); done = 1; } + if((source[sp] >= '0') && (source[sp] <= '9')) { edi_count += (2.0 / 3.0); done = 1; } + if((source[sp] >= 'A') && (source[sp] <= 'Z')) { edi_count += (2.0 / 3.0); done = 1; } + if(source[sp] > 127) { + edi_count += (13.0 / 3.0); + } else { + if(done == 0) { + edi_count += (10.0 / 3.0); + } + } + + /* Step P */ + if(gs1 && (source[sp] == '[')) { byte_count += 3.0; } else { byte_count += 1.0; } + + } + + ascii_count = froundup(ascii_count); + c40_count = froundup(c40_count); + text_count = froundup(text_count); + edi_count = froundup(edi_count); + byte_count = froundup(byte_count); + best_scheme = C1_ASCII; + + if(sp == sourcelen) { + /* Step K */ + best_count = edi_count; + + if(text_count <= best_count) { + best_count = text_count; + best_scheme = C1_TEXT; + } + + if(c40_count <= best_count) { + best_count = c40_count; + best_scheme = C1_C40; + } + + if(ascii_count <= best_count) { + best_count = ascii_count; + best_scheme = C1_ASCII; + } + + if(byte_count <= best_count) { + best_count = byte_count; + best_scheme = C1_BYTE; + } + } else { + /* Step Q */ + + if(((edi_count + 1.0 <= ascii_count) && (edi_count + 1.0 <= c40_count)) && + ((edi_count + 1.0 <= byte_count) && (edi_count + 1.0 <= text_count))) { + best_scheme = C1_EDI; + } + + if((c40_count + 1.0 <= ascii_count) && (c40_count + 1.0 <= text_count)) { + + if(c40_count < edi_count) { + best_scheme = C1_C40; + } else { + done = 0; + if(c40_count == edi_count) { + if(dq4bi(source, sourcelen, position)) { + best_scheme = C1_EDI; + } else { + best_scheme = C1_C40; + } + } + } + } + + if(((text_count + 1.0 <= ascii_count) && (text_count + 1.0 <= c40_count)) && + ((text_count + 1.0 <= byte_count) && (text_count + 1.0 <= edi_count))) { + best_scheme = C1_TEXT; + } + + if(((ascii_count + 1.0 <= byte_count) && (ascii_count + 1.0 <= c40_count)) && + ((ascii_count + 1.0 <= text_count) && (ascii_count + 1.0 <= edi_count))) { + best_scheme = C1_ASCII; + } + + if(((byte_count + 1.0 <= ascii_count) && (byte_count + 1.0 <= c40_count)) && + ((byte_count + 1.0 <= text_count) && (byte_count + 1.0 <= edi_count))) { + best_scheme = C1_BYTE; + } + } + + //printf("\n> scores: ASCII %.2f C40 %.2f TEXT %.2f EDI %.2f BYTE %.2f\n", ascii_count, c40_count, text_count, edi_count, byte_count); + + return best_scheme; +} + +int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int target[], int length) +{ + int current_mode, next_mode; + int sp, tp, gs1, i, j, latch; + int c40_buffer[6], c40_p; + int text_buffer[6], text_p; + int edi_buffer[6], edi_p; + char decimal_binary[40]; + int byte_start = 0; + + sp = 0; + tp = 0; + latch = 0; + memset(c40_buffer, 0, 6); + c40_p = 0; + memset(text_buffer, 0, 6); + text_p = 0; + memset(edi_buffer, 0, 6); + edi_p = 0; + strcpy(decimal_binary, ""); + + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + if(gs1) { target[tp] = 232; tp++; } /* FNC1 */ + + /* Step A */ + current_mode = C1_ASCII; + next_mode = C1_ASCII; + + do { + if(current_mode != next_mode) { + /* Change mode */ + switch(next_mode) { + case C1_C40: target[tp] = 230; tp++; break; + case C1_TEXT: target[tp] = 239; tp++; break; + case C1_EDI: target[tp] = 238; tp++; break; + case C1_BYTE: target[tp] = 231; tp++; break; + } + } + + if((current_mode != C1_BYTE) && (next_mode == C1_BYTE)) { byte_start = tp; } + current_mode = next_mode; + + if(current_mode == C1_ASCII) { /* Step B - ASCII encodation */ + next_mode = C1_ASCII; + + if((length - sp) >= 21) { /* Step B1 */ + j = 0; + + for(i = 0; i < 21; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 21) { + next_mode = C1_DECIMAL; + strcpy(decimal_binary, "1111"); + } + } + + if((next_mode == C1_ASCII) && ((length - sp) >= 13)) { /* Step B2 */ + j = 0; + + for(i = 0; i < 13; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 13) { + latch = 0; + for(i = sp + 13; i < length; i++) { + if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; } + } + + if(!(latch)) { + next_mode = C1_DECIMAL; + strcpy(decimal_binary, "1111"); + } + } + } + + if(next_mode == C1_ASCII) { /* Step B3 */ + if(istwodigits(source, sp) && ((sp + 1) != length)) { + target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; + tp++; + sp += 2; + } else { + if((gs1) && (source[sp] == '[')) { + if((length - sp) >= 15) { /* Step B4 */ + j = 0; + + for(i = 0; i < 15; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 15) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; sp++; + next_mode = C1_DECIMAL; + } + } + + if((length - sp) >= 7) { /* Step B5 */ + j = 0; + + for(i = 0; i < 7; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 7) { + latch = 0; + for(i = sp + 7; i < length; i++) { + if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; } + } + + if(!(latch)) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; sp++; + next_mode = C1_DECIMAL; + } + } + } + } + + if(next_mode == C1_ASCII) { + + /* Step B6 */ + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + + if(next_mode == C1_ASCII) { + if(source[sp] > 127) { + /* Step B7 */ + target[tp] = 235; tp++; /* FNC4 */ + target[tp] = (source[sp] - 128) + 1; tp++; sp++; + } else { + /* Step B8 */ + if((gs1) && (source[sp] == '[')) { + target[tp] = 232; tp++; sp++; /* FNC1 */ + } else { + target[tp] = source[sp] + 1; tp++; sp++; + } + } + } + } + } + } + } + + if(current_mode == C1_C40) { /* Step C - C40 encodation */ + int shift_set, value, done = 0, latch = 0; + + next_mode = C1_C40; + if(c40_p == 0) { + if((length - sp) >= 12) { + j = 0; + + for(i = 0; i < 12; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 12) { + next_mode = C1_ASCII; done = 1; + } + } + + if((length - sp) >= 8) { + j = 0; + + for(i = 0; i < 8; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for(j = sp + 8; j < length; j++) { + if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; done = 1; + } + } + + if(!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if(next_mode != C1_C40) { + target[tp] = 255; tp++; /* Unlatch */ + } else { + if(source[sp] > 127) { + c40_buffer[c40_p] = 1; c40_p++; + c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */ + shift_set = c40_shift[source[sp] - 128]; + value = c40_value[source[sp] - 128]; + } else { + shift_set = c40_shift[source[sp]]; + value = c40_value[source[sp]]; + } + + if(gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if(shift_set != 0) { + c40_buffer[c40_p] = shift_set - 1; c40_p++; + } + c40_buffer[c40_p] = value; c40_p++; + + if(c40_p >= 3) { + int iv; + + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + + c40_buffer[0] = c40_buffer[3]; + c40_buffer[1] = c40_buffer[4]; + c40_buffer[2] = c40_buffer[5]; + c40_buffer[3] = 0; + c40_buffer[4] = 0; + c40_buffer[5] = 0; + c40_p -= 3; + } + sp++; + } + } + + if(current_mode == C1_TEXT) { /* Step D - Text encodation */ + int shift_set, value, done = 0, latch = 0; + + next_mode = C1_TEXT; + if(text_p == 0) { + if((length - sp) >= 12) { + j = 0; + + for(i = 0; i < 12; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 12) { + next_mode = C1_ASCII; done = 1; + } + } + + if((length - sp) >= 8) { + j = 0; + + for(i = 0; i < 8; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for(j = sp + 8; j < length; j++) { + if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; done = 1; + } + } + + if(!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if(next_mode != C1_TEXT) { + target[tp] = 255; tp++; /* Unlatch */ + } else { + if(source[sp] > 127) { + text_buffer[text_p] = 1; text_p++; + text_buffer[text_p] = 30; text_p++; /* Upper Shift */ + shift_set = text_shift[source[sp] - 128]; + value = text_value[source[sp] - 128]; + } else { + shift_set = text_shift[source[sp]]; + value = text_value[source[sp]]; + } + + if(gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if(shift_set != 0) { + text_buffer[text_p] = shift_set - 1; text_p++; + } + text_buffer[text_p] = value; text_p++; + + if(text_p >= 3) { + int iv; + + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + + text_buffer[0] = text_buffer[3]; + text_buffer[1] = text_buffer[4]; + text_buffer[2] = text_buffer[5]; + text_buffer[3] = 0; + text_buffer[4] = 0; + text_buffer[5] = 0; + text_p -= 3; + } + sp++; + } + } + + if(current_mode == C1_EDI) { /* Step E - EDI Encodation */ + int value = 0, done = 0, latch = 0; + + next_mode = C1_EDI; + if(edi_p == 0) { + if((length - sp) >= 12) { + j = 0; + + for(i = 0; i < 12; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if (j == 12) { + next_mode = C1_ASCII; done = 1; + } + } + + if((length - sp) >= 8) { + j = 0; + + for(i = 0; i < 8; i++) { + if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } + } + + if((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for(j = sp + 8; j < length; j++) { + if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; done = 1; + } + } + + if(!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) { + next_mode = C1_ASCII; + } + } + + if(next_mode != C1_EDI) { + target[tp] = 255; tp++; /* Unlatch */ + } else { + if(source[sp] == 13) { value = 0; } + if(source[sp] == '*') { value = 1; } + if(source[sp] == '>') { value = 2; } + if(source[sp] == ' ') { value = 3; } + if((source[sp] >= '0') && (source[sp] <= '9')) { value = source[sp] - '0' + 4; } + if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = source[sp] - 'A' + 14; } + + edi_buffer[edi_p] = value; edi_p++; + + if(edi_p >= 3) { + int iv; + + iv = (1600 * edi_buffer[0]) + (40 * edi_buffer[1]) + (edi_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + + edi_buffer[0] = edi_buffer[3]; + edi_buffer[1] = edi_buffer[4]; + edi_buffer[2] = edi_buffer[5]; + edi_buffer[3] = 0; + edi_buffer[4] = 0; + edi_buffer[5] = 0; + edi_p -= 3; + } + sp++; + } + } + + if(current_mode == C1_DECIMAL) { /* Step F - Decimal encodation */ + int value, decimal_count, data_left; + + next_mode = C1_DECIMAL; + + data_left = length - sp; + decimal_count = 0; + + if(data_left >= 1) { + if((source[sp] >= '0') && (source[sp] <= '9')) { decimal_count = 1; } + } + if(data_left >= 2) { + if((decimal_count == 1) && ((source[sp + 1] >= '0') && (source[sp + 1] <= '9'))) { decimal_count = 2; } + } + if(data_left >= 3) { + if((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) { decimal_count = 3; } + } + + if(decimal_count != 3) { + int bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + concat(decimal_binary, "111111"); /* Unlatch */ + + target_count = 3; + if(strlen(decimal_binary) <= 16) { target_count = 2; } + if(strlen(decimal_binary) <= 8) { target_count = 1; } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if(bits_left_in_byte == 8) { bits_left_in_byte = 0; } + + if(bits_left_in_byte == 2) { + concat(decimal_binary, "01"); + } + + if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + if(decimal_count >= 1) { + int sub_value = ctoi(source[sp]) + 1; + + if(sub_value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(sub_value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(sub_value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(sub_value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + sp++; + } else { + concat(decimal_binary, "1111"); + } + } + + if(bits_left_in_byte == 6) { + concat(decimal_binary, "01"); + } + + /* Binary buffer is full - transfer to target */ + if(target_count >= 1) { + sub_target = 0; + if(decimal_binary[0] == '1') { sub_target += 128; } + if(decimal_binary[1] == '1') { sub_target += 64; } + if(decimal_binary[2] == '1') { sub_target += 32; } + if(decimal_binary[3] == '1') { sub_target += 16; } + if(decimal_binary[4] == '1') { sub_target += 8; } + if(decimal_binary[5] == '1') { sub_target += 4; } + if(decimal_binary[6] == '1') { sub_target += 2; } + if(decimal_binary[7] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + if(target_count >= 2) { + sub_target = 0; + if(decimal_binary[8] == '1') { sub_target += 128; } + if(decimal_binary[9] == '1') { sub_target += 64; } + if(decimal_binary[10] == '1') { sub_target += 32; } + if(decimal_binary[11] == '1') { sub_target += 16; } + if(decimal_binary[12] == '1') { sub_target += 8; } + if(decimal_binary[13] == '1') { sub_target += 4; } + if(decimal_binary[14] == '1') { sub_target += 2; } + if(decimal_binary[15] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + if(target_count == 3) { + sub_target = 0; + if(decimal_binary[16] == '1') { sub_target += 128; } + if(decimal_binary[17] == '1') { sub_target += 64; } + if(decimal_binary[18] == '1') { sub_target += 32; } + if(decimal_binary[19] == '1') { sub_target += 16; } + if(decimal_binary[20] == '1') { sub_target += 8; } + if(decimal_binary[21] == '1') { sub_target += 4; } + if(decimal_binary[22] == '1') { sub_target += 2; } + if(decimal_binary[23] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + + next_mode = C1_ASCII; + } else { + /* There are three digits - convert the value to binary */ + value = (100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1; + + if(value & 0x200) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x100) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x80) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x40) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x20) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x10) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + if(value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } + + sp+= 3; + } + + if(strlen(decimal_binary) >= 24) { + int target1 = 0, target2 = 0, target3 = 0; + char temp_binary[40]; + + /* Binary buffer is full - transfer to target */ + if(decimal_binary[0] == '1') { target1 += 128; } + if(decimal_binary[1] == '1') { target1 += 64; } + if(decimal_binary[2] == '1') { target1 += 32; } + if(decimal_binary[3] == '1') { target1 += 16; } + if(decimal_binary[4] == '1') { target1 += 8; } + if(decimal_binary[5] == '1') { target1 += 4; } + if(decimal_binary[6] == '1') { target1 += 2; } + if(decimal_binary[7] == '1') { target1 += 1; } + if(decimal_binary[8] == '1') { target2 += 128; } + if(decimal_binary[9] == '1') { target2 += 64; } + if(decimal_binary[10] == '1') { target2 += 32; } + if(decimal_binary[11] == '1') { target2 += 16; } + if(decimal_binary[12] == '1') { target2 += 8; } + if(decimal_binary[13] == '1') { target2 += 4; } + if(decimal_binary[14] == '1') { target2 += 2; } + if(decimal_binary[15] == '1') { target2 += 1; } + if(decimal_binary[16] == '1') { target3 += 128; } + if(decimal_binary[17] == '1') { target3 += 64; } + if(decimal_binary[18] == '1') { target3 += 32; } + if(decimal_binary[19] == '1') { target3 += 16; } + if(decimal_binary[20] == '1') { target3 += 8; } + if(decimal_binary[21] == '1') { target3 += 4; } + if(decimal_binary[22] == '1') { target3 += 2; } + if(decimal_binary[23] == '1') { target3 += 1; } + target[tp] = target1; tp++; + target[tp] = target2; tp++; + target[tp] = target3; tp++; + + strcpy(temp_binary, ""); + if(strlen(decimal_binary) > 24) { + for(i = 0; i <= (strlen(decimal_binary) - 24); i++) { + temp_binary[i] = decimal_binary[i + 24]; + } + strcpy(decimal_binary, temp_binary); + } + } + } + + if(current_mode == C1_BYTE) { + next_mode = C1_BYTE; + + if(gs1 && (source[sp] == '[')) { + next_mode = C1_ASCII; + } else { + if(source[sp] <= 127) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if(next_mode != C1_BYTE) { + /* Insert byte field length */ + if((tp - byte_start) <= 249) { + for(i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for(i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } else { + target[tp] = source[sp]; + tp++; + sp++; + } + } + + if(tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "Input data too long"); + return 0; + } + } while (sp < length); + + /* Empty buffers */ + if(c40_p == 2) { + int iv; + + c40_buffer[2] = 1; + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + target[tp] = 255; tp++; /* Unlatch */ + } + if(c40_p == 1) { + int iv; + + c40_buffer[1] = 1; + c40_buffer[2] = 31; /* Pad */ + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + target[tp] = 255; tp++; /* Unlatch */ + } + if(text_p == 2) { + int iv; + + text_buffer[2] = 1; + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + target[tp] = 255; tp++; /* Unlatch */ + } + if(text_p == 1) { + int iv; + + text_buffer[1] = 1; + text_buffer[2] = 31; /* Pad */ + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + target[tp] = 255; tp++; /* Unlatch */ + } + + if(current_mode == C1_DECIMAL) { + int bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + concat(decimal_binary, "111111"); /* Unlatch */ + + target_count = 3; + if(strlen(decimal_binary) <= 16) { target_count = 2; } + if(strlen(decimal_binary) <= 8) { target_count = 1; } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if(bits_left_in_byte == 8) { bits_left_in_byte = 0; } + + if(bits_left_in_byte == 2) { + concat(decimal_binary, "01"); + } + + if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + concat(decimal_binary, "1111"); + } + + if(bits_left_in_byte == 6) { + concat(decimal_binary, "01"); + } + + /* Binary buffer is full - transfer to target */ + if(target_count >= 1) { + sub_target = 0; + if(decimal_binary[0] == '1') { sub_target += 128; } + if(decimal_binary[1] == '1') { sub_target += 64; } + if(decimal_binary[2] == '1') { sub_target += 32; } + if(decimal_binary[3] == '1') { sub_target += 16; } + if(decimal_binary[4] == '1') { sub_target += 8; } + if(decimal_binary[5] == '1') { sub_target += 4; } + if(decimal_binary[6] == '1') { sub_target += 2; } + if(decimal_binary[7] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + if(target_count >= 2) { + sub_target = 0; + if(decimal_binary[8] == '1') { sub_target += 128; } + if(decimal_binary[9] == '1') { sub_target += 64; } + if(decimal_binary[10] == '1') { sub_target += 32; } + if(decimal_binary[11] == '1') { sub_target += 16; } + if(decimal_binary[12] == '1') { sub_target += 8; } + if(decimal_binary[13] == '1') { sub_target += 4; } + if(decimal_binary[14] == '1') { sub_target += 2; } + if(decimal_binary[15] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + if(target_count == 3) { + sub_target = 0; + if(decimal_binary[16] == '1') { sub_target += 128; } + if(decimal_binary[17] == '1') { sub_target += 64; } + if(decimal_binary[18] == '1') { sub_target += 32; } + if(decimal_binary[19] == '1') { sub_target += 16; } + if(decimal_binary[20] == '1') { sub_target += 8; } + if(decimal_binary[21] == '1') { sub_target += 4; } + if(decimal_binary[22] == '1') { sub_target += 2; } + if(decimal_binary[23] == '1') { sub_target += 1; } + target[tp] = sub_target; tp++; + } + } + + if(current_mode == C1_BYTE) { + /* Insert byte field length */ + if((tp - byte_start) <= 249) { + for(i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for(i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } + + /* Re-check length of data */ + if(tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "Input data too long"); + return 0; + } + /* + printf("targets:\n"); + for(i = 0; i < tp; i++) { + printf("[%d]", target[i]); + } + printf("\n"); + */ + return tp; +} + +void block_copy(struct zint_symbol *symbol, char grid[][120], int start_row, int start_col, int height, int width, int row_offset, int col_offset) { + int i, j; + + for(i = start_row; i < (start_row + height); i++) { + for(j = start_col; j < (start_col + width); j++) { + if(grid[i][j] == '1') { + set_module(symbol, i + row_offset, j + col_offset); + } + } + } +} + +int code_one(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int size = 1, i, j, data_blocks; + + char datagrid[136][120]; + int row, col; + int sub_version = 0; + + if((symbol->option_2 < 0) || (symbol->option_2 > 10)) { + strcpy(symbol->errtxt, "Invalid symbol size"); + return ERROR_INVALID_OPTION; + } + + if(symbol->option_2 == 9) { + /* Version S */ + int codewords; + short int elreg[112]; + unsigned int data[15], ecc[15]; + int stream[30]; + int block_width; + + if(length > 18) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + if(is_sane(NEON, source, length) == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid input data (Version S encodes numeric input only)"); + return ERROR_INVALID_DATA; + } + + sub_version = 3; codewords = 12; block_width = 6; /* Version S-30 */ + if(length <= 12) { sub_version = 2; codewords = 8; block_width = 4; } /* Version S-20 */ + if(length <= 6) { sub_version = 1; codewords = 4; block_width = 2; } /* Version S-10 */ + + binary_load(elreg, (char *)source, length); + hex_dump(elreg); + + for(i = 0; i < 15; i++) { + data[i] = 0; + ecc[i] = 0; + } + + for(i = 0; i < codewords; i++) { + data[codewords - i - 1] += 1 * elreg[(i * 5)]; + data[codewords - i - 1] += 2 * elreg[(i * 5) + 1]; + data[codewords - i - 1] += 4 * elreg[(i * 5) + 2]; + data[codewords - i - 1] += 8 * elreg[(i * 5) + 3]; + data[codewords - i - 1] += 16 * elreg[(i * 5) + 4]; + } + + rs_init_gf(0x25); + rs_init_code(codewords, 1); + rs_encode_long(codewords, data, ecc); + rs_free(); + + for(i = 0; i < codewords; i++) { + stream[i] = data[i]; + stream[i + codewords] = ecc[codewords - i - 1]; + } + + for(i = 0; i < 136; i++) { + for(j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for(row = 0; row < 2; row++) { + for(col = 0; col < block_width; col++) { + if(stream[i] & 0x10) { datagrid[row * 2][col * 5] = '1'; } + if(stream[i] & 0x08) { datagrid[row * 2][(col * 5) + 1] = '1'; } + if(stream[i] & 0x04) { datagrid[row * 2][(col * 5) + 2] = '1'; } + if(stream[i] & 0x02) { datagrid[(row * 2) + 1][col * 5] = '1'; } + if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 1] = '1'; } + if(stream[i + 1] & 0x10) { datagrid[row * 2][(col * 5) + 3] = '1'; } + if(stream[i + 1] & 0x08) { datagrid[row * 2][(col * 5) + 4] = '1'; } + if(stream[i + 1] & 0x04) { datagrid[(row * 2) + 1][(col * 5) + 2] = '1'; } + if(stream[i + 1] & 0x02) { datagrid[(row * 2) + 1][(col * 5) + 3] = '1'; } + if(stream[i + 1] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 4] = '1'; } + i += 2; + } + } + + size = 9; + symbol->rows = 8; + symbol->width = 10 * sub_version + 1; + } + + if(symbol->option_2 == 10) { + /* Version T */ + unsigned int data[40], ecc[25]; + unsigned int stream[65]; + int data_length; + int data_cw, ecc_cw, block_width; + + for(i = 0; i < 40; i++) { data[i] = 0; } + data_length = c1_encode(symbol, source, data, length); + + if(data_length == 0) { + return ERROR_TOO_LONG; + } + + if(data_length > 38) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + + size = 10; + sub_version = 3; data_cw = 38; ecc_cw = 22; block_width = 12; + if(data_length <= 24) { sub_version = 2; data_cw = 24; ecc_cw = 16; block_width = 8; } + if(data_length <= 10) { sub_version = 1; data_cw = 10; ecc_cw = 10; block_width = 4; } + + for(i = data_length; i < data_cw; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + rs_init_gf(0x12d); + rs_init_code(ecc_cw, 1); + rs_encode_long(data_cw, data, ecc); + rs_free(); + + /* "Stream" combines data and error correction data */ + for(i = 0; i < data_cw; i++) { + stream[i] = data[i]; + } + for(i = 0; i < ecc_cw; i++) { + stream[data_cw + i] = ecc[ecc_cw - i - 1]; + } + + for(i = 0; i < 136; i++) { + for(j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for(row = 0; row < 5; row++) { + for(col = 0; col < block_width; col++) { + if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; } + if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; } + if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; } + if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; } + if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; } + if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; } + if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; } + if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; } + i++; + } + } + + symbol->rows = 16; + symbol->width = (sub_version * 16) + 1; + } + + if((symbol->option_2 != 9) && (symbol->option_2 != 10)) { + /* Version A to H */ + unsigned int data[1500], ecc[600]; + unsigned int sub_data[190], sub_ecc[75]; + unsigned int stream[2100]; + int data_length; + + for(i = 0; i < 1500; i++) { data[i] = 0; } + data_length = c1_encode(symbol, source, data, length); + + if(data_length == 0) { + return ERROR_TOO_LONG; + } + + for(i = 7; i >= 0; i--) { + if(c1_data_length[i] >= data_length) { + size = i + 1; + } + } + + if(symbol->option_2 > size) { + size = symbol->option_2; + } + + for(i = data_length; i < c1_data_length[size - 1]; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + data_length = c1_data_length[size - 1]; + for(i = 0; i < 190; i++) { sub_data[i] = 0; } + for(i = 0; i < 75; i++) { sub_ecc[i] = 0; } + + data_blocks = c1_blocks[size - 1]; + + /* + Section 2.2.5.1 states: + "The polynomial arithmetic... is calculated using bit-wise modulo 2 arithmetic + and byte-wise modulo 100101101 arithmetic (this is a Galois Field of 2^8 with + 100101101 representing the field's prime modulus polynomial: + x^8 + x^5 + x^3 + x^2 + 1)." + This is the same as Data Matrix (ISO/IEC 16022) however the calculations in Appendix F + of the Code One specification do not agree with those in Annex E of ISO/IEC 16022. + For example Code One Appendix F states: + "The polynomial divisor for generating ten check characters for Version T-16 + and Version A is: + g(x)=x^10 + 136x^9 + 141x^8 + 113x^7 + 76x^6 + 218x^5 + 43x^4 + 85x^3 + + 182x^2 + 31x + 52." + Whereas ISO/IEC 16022 Annex E states: + "The polynomial divisor for generating 10 check characters is: + g(x)=x^10 + 61x^9 + 110x^8 + 255x^7 + 116x^6 + 248x^5 + 223x^4 + 166x^3 + + 185x^2 + 24x + 28." + For this code I have assumed that ISO/IEC 16022 is correct and the USS Code One + specifications are incorrect + */ + + rs_init_gf(0x12d); + rs_init_code(c1_ecc_blocks[size - 1], 1); + for(i = 0; i < data_blocks; i++) { + for(j = 0; j < c1_data_blocks[size - 1]; j++) { + + sub_data[j] = data[j * data_blocks + i]; + } + rs_encode_long(c1_data_blocks[size - 1], sub_data, sub_ecc); + for(j = 0; j < c1_ecc_blocks[size - 1]; j++) { + ecc[c1_ecc_length[size - 1] - (j * data_blocks + i) - 1] = sub_ecc[j]; + } + } + rs_free(); + + /* "Stream" combines data and error correction data */ + for(i = 0; i < data_length; i++) { + stream[i] = data[i]; + } + for(i = 0; i < c1_ecc_length[size - 1]; i++) { + stream[data_length + i] = ecc[i]; + } + + for(i = 0; i < 136; i++) { + for(j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for(row = 0; row < c1_grid_height[size - 1]; row++) { + for(col = 0; col < c1_grid_width[size - 1]; col++) { + if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; } + if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; } + if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; } + if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; } + if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; } + if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; } + if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; } + if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; } + i++; + } + } + + /* for(i = 0; i < (c1_grid_height[size - 1] * 2); i++) { + for(j = 0; j < (c1_grid_width[size - 1] * 4); j++) { + printf("%c", datagrid[i][j]); + } + printf("\n"); + } */ + + symbol->rows = c1_height[size - 1]; + symbol->width = c1_width[size - 1]; + } + + switch(size) { + case 1: /* Version A */ + central_finder(symbol, 6, 3, 1); + vert(symbol, 4, 6, 1); + vert(symbol, 12, 5, 0); + set_module(symbol, 5, 12); + spigot(symbol, 0); + spigot(symbol, 15); + block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2); + block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0); + block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2); + break; + case 2: /* Version B */ + central_finder(symbol, 8, 4, 1); + vert(symbol, 4, 8, 1); + vert(symbol, 16, 7, 0); + set_module(symbol, 7, 16); + spigot(symbol, 0); + spigot(symbol, 21); + block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2); + block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0); + block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2); + break; + case 3: /* Version C */ + central_finder(symbol, 11, 4, 2); + vert(symbol, 4, 11, 1); + vert(symbol, 26, 13, 1); + vert(symbol, 4, 10, 0); + vert(symbol, 26, 10, 0); + spigot(symbol, 0); + spigot(symbol, 27); + block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4); + block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0); + block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2); + block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4); + break; + case 4: /* Version D */ + central_finder(symbol, 16, 5, 1); + vert(symbol, 4, 16, 1); + vert(symbol, 20, 16, 1); + vert(symbol, 36, 16, 1); + vert(symbol, 4, 15, 0); + vert(symbol, 20, 15, 0); + vert(symbol, 36, 15, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 27); + spigot(symbol, 39); + block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2); + block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4); + block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6); + block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0); + block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2); + block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4); + block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6); + break; + case 5: /* Version E */ + central_finder(symbol, 22, 5, 2); + vert(symbol, 4, 22, 1); + vert(symbol, 26, 24, 1); + vert(symbol, 48, 22, 1); + vert(symbol, 4, 21, 0); + vert(symbol, 26, 21, 0); + vert(symbol, 48, 21, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 39); + spigot(symbol, 51); + block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6); + block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0); + block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2); + block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4); + block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6); + break; + case 6: /* Version F */ + central_finder(symbol, 31, 5, 3); + vert(symbol, 4, 31, 1); + vert(symbol, 26, 35, 1); + vert(symbol, 48, 31, 1); + vert(symbol, 70, 35, 1); + vert(symbol, 4, 30, 0); + vert(symbol, 26, 30, 0); + vert(symbol, 48, 30, 0); + vert(symbol, 70, 30, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 45); + spigot(symbol, 57); + spigot(symbol, 69); + block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6); + block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8); + block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0); + block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2); + block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4); + block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6); + block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8); + break; + case 7: /* Version G */ + central_finder(symbol, 47, 6, 2); + vert(symbol, 6, 47, 1); + vert(symbol, 27, 49, 1); + vert(symbol, 48, 47, 1); + vert(symbol, 69, 49, 1); + vert(symbol, 90, 47, 1); + vert(symbol, 6, 46, 0); + vert(symbol, 27, 46, 0); + vert(symbol, 48, 46, 0); + vert(symbol, 69, 46, 0); + vert(symbol, 90, 46, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 67); + spigot(symbol, 79); + spigot(symbol, 91); + spigot(symbol, 103); + block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2); + block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4); + block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6); + block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8); + block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10); + block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0); + block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2); + block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4); + block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6); + block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8); + block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10); + break; + case 8: /* Version H */ + central_finder(symbol, 69, 6, 3); + vert(symbol, 6, 69, 1); + vert(symbol, 26, 73, 1); + vert(symbol, 46, 69, 1); + vert(symbol, 66, 73, 1); + vert(symbol, 86, 69, 1); + vert(symbol, 106, 73, 1); + vert(symbol, 126, 69, 1); + vert(symbol, 6, 68, 0); + vert(symbol, 26, 68, 0); + vert(symbol, 46, 68, 0); + vert(symbol, 66, 68, 0); + vert(symbol, 86, 68, 0); + vert(symbol, 106, 68, 0); + vert(symbol, 126, 68, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 48); + spigot(symbol, 60); + spigot(symbol, 87); + spigot(symbol, 99); + spigot(symbol, 111); + spigot(symbol, 123); + spigot(symbol, 135); + spigot(symbol, 147); + block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2); + block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4); + block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6); + block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8); + block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10); + block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12); + block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14); + block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0); + block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2); + block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4); + block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6); + block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8); + block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10); + block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12); + block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14); + break; + case 9: /* Version S */ + horiz(symbol, 5, 1); + horiz(symbol, 7, 1); + set_module(symbol, 6, 0); + set_module(symbol, 6, symbol->width - 1); + unset_module(symbol, 7, 1); + unset_module(symbol, 7, symbol->width - 2); + switch(sub_version) { + case 1: /* Version S-10 */ + set_module(symbol, 0, 5); + block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0); + block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1); + break; + case 2: /* Version S-20 */ + set_module(symbol, 0, 10); + set_module(symbol, 4, 10); + block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0); + block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1); + break; + case 3: /* Version S-30 */ + set_module(symbol, 0, 15); + set_module(symbol, 4, 15); + set_module(symbol, 6, 15); + block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0); + block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1); + break; + } + break; + case 10: /* Version T */ + horiz(symbol, 11, 1); + horiz(symbol, 13, 1); + horiz(symbol, 15, 1); + set_module(symbol, 12, 0); + set_module(symbol, 12, symbol->width - 1); + set_module(symbol, 14, 0); + set_module(symbol, 14, symbol->width - 1); + unset_module(symbol, 13, 1); + unset_module(symbol, 13, symbol->width - 2); + unset_module(symbol, 15, 1); + unset_module(symbol, 15, symbol->width - 2); + switch(sub_version) { + case 1: /* Version T-16 */ + set_module(symbol, 0, 8); + set_module(symbol, 10, 8); + block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0); + block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1); + break; + case 2: /* Version T-32 */ + set_module(symbol, 0, 16); + set_module(symbol, 10, 16); + set_module(symbol, 12, 16); + block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0); + block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1); + break; + case 3: /* Verion T-48 */ + set_module(symbol, 0, 24); + set_module(symbol, 10, 24); + set_module(symbol, 12, 24); + set_module(symbol, 14, 24); + block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0); + block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1); + break; + } + break; + } + + for(i = 0; i < symbol->rows; i++) { + symbol->row_height[i] = 1; + } + + return 0; +} diff --git a/backend/code1.h b/backend/code1.h new file mode 100644 index 00000000..532dc771 --- /dev/null +++ b/backend/code1.h @@ -0,0 +1,61 @@ +/* code1.h - Lookup info for USS Code One */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +static int c40_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + +static int c40_value[] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, + 15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, + 22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; + +static int text_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 }; + +static int text_value[] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, + 15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, + 22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 }; + +static int c1_height[] = { 16, 22, 28, 40, 52, 70, 104, 148 }; +static int c1_width[] = { 18, 22, 32, 42, 54, 76, 98, 134 }; +static int c1_data_length[] = { 10, 19, 44, 91, 182, 370, 732, 1480 }; +static int c1_ecc_length[] = { 10, 16, 26, 44, 70, 140, 280, 560 }; +static int c1_blocks[] = { 1, 1, 1, 1, 1, 2, 4, 8 }; +static int c1_data_blocks[] = { 10, 19, 44, 91, 182, 185, 183, 185 }; +static int c1_ecc_blocks[] = { 10, 16, 26, 44, 70, 70, 70, 70 }; +static int c1_grid_width[] = { 4, 5, 7, 9, 12, 17, 22, 30 }; +static int c1_grid_height[] = { 5, 7, 10, 15, 21, 30, 46, 68 }; + +#define C1_ASCII 1 +#define C1_C40 2 +#define C1_DECIMAL 3 +#define C1_TEXT 4 +#define C1_EDI 5 +#define C1_BYTE 6 \ No newline at end of file diff --git a/backend/code128.c b/backend/code128.c new file mode 100644 index 00000000..ed8043a2 --- /dev/null +++ b/backend/code128.c @@ -0,0 +1,999 @@ +/* code128.c - Handles Code 128 and derivatives */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + Bugfixes thanks to Christian Sakowski and BogDan Vatra + + 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 +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define TRUE 1 +#define FALSE 0 +#define SHIFTA 90 +#define LATCHA 91 +#define SHIFTB 92 +#define LATCHB 93 +#define SHIFTC 94 +#define LATCHC 95 +#define AORB 96 +#define ABORC 97 + +#define DPDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*" + +static int list[2][170]; + +/* Code 128 tables checked against ISO/IEC 15417:2007 */ + +static char *C128Table[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213", + "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", + "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", + "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", + "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", + "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", + "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", + "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", + "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", + "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", + "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", + "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", + "2331112"}; +/* Code 128 character encodation - Table 1 */ + +int parunmodd(unsigned char llyth) +{ + int modd; + modd = 0; + + if(llyth <= 31) { modd = SHIFTA; } + else if((llyth >= 48) && (llyth <= 57)) { modd = ABORC; } + else if(llyth <= 95) { modd = AORB; } + else if(llyth <= 127) { modd = SHIFTB; } + else if(llyth <= 159) { modd = SHIFTA; } + else if(llyth <= 223) { modd = AORB; } + else { modd = SHIFTB; } + + return modd; +} + +void grwp(int *indexliste) +{ + int i, j; + + /* bring together same type blocks */ + if(*(indexliste) > 1) { + i = 1; + while(i < *(indexliste)) { + if(list[1][i - 1] == list[1][i]) { + /* bring together */ + list[0][i - 1] = list[0][i - 1] + list[0][i]; + j = i + 1; + + /* decreace the list */ + while(j < *(indexliste)) { + list[0][j - 1] = list[0][j]; + list[1][j - 1] = list[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } +} + +void dxsmooth(int *indexliste) +{ /* Implements rules from ISO 15417 Annex E */ + int i, current, last, next, length; + + for(i = 0; i < *(indexliste); i++) { + current = list[1][i]; + length = list[0][i]; + if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; } + if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; } + + if(i == 0) { /* first block */ + if((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; } + if(current == ABORC) { + if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; 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) { /* Rule 1d */ list[1][i] = LATCHB; } + } else { + if((current == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; current = LATCHC; } + if(current == ABORC) { list[1][i] = AORB; current = AORB; } + if((current == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } + 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) { list[1][i] = LATCHB; current = LATCHB; } + if((current == SHIFTA) && (length > 1)) { /* 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); + +} + +void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) +{ /* Translate Code 128 Set A characters into barcodes */ + /* This set handles all control characters NULL to US */ + + if(source > 127) { + if(source < 160) { + concat(dest, C128Table[(source - 128) + 64]); + values[(*bar_chars)] = (source - 128) + 64; + } else { + concat(dest, C128Table[(source - 128) - 32]); + values[(*bar_chars)] = (source - 128) - 32; + } + } else { + if(source < 32) { + concat(dest, C128Table[source + 64]); + values[(*bar_chars)] = source + 64; + } else { + concat(dest, C128Table[source - 32]); + values[(*bar_chars)] = source - 32; + } + } + (*bar_chars)++; +} + +void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars) +{ /* Translate Code 128 Set B characters into barcodes */ + /* This set handles all characters which are not part of long numbers and not control characters */ + + if(source > 127) { + concat(dest, C128Table[source - 32 - 128]); + values[(*bar_chars)] = source - 32 - 128; + } else { + concat(dest, C128Table[source - 32]); + values[(*bar_chars)] = source - 32; + } + (*bar_chars)++; +} + +void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars) +{ /* Translate Code 128 Set C characters into barcodes */ + /* This set handles numbers in a compressed form */ + int weight; + + weight = (10 * ctoi(source_a)) + ctoi(source_b); + concat(dest, C128Table[weight]); + values[(*bar_chars)] = weight; + (*bar_chars)++; +} + +int code_128(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Handle Code 128 and NVE-18 */ + int i, j, k, e_count, values[170] = { 0 }, bar_characters, read, total_sum, nve_check; + int error_number, indexchaine, indexliste, sourcelen, f_state; + char set[170] = { ' ' }, fset[170] = { ' ' }, mode, last_set, last_fset, current_set = ' '; + float glyph_count; + char dest[1000]; + + error_number = 0; + strcpy(dest, ""); + + sourcelen = length; + + j = 0; + e_count = 0; + bar_characters = 0; + nve_check = 0; + f_state = 0; + + if(sourcelen > 160) { + /* This only blocks rediculously long input - the actual length of the + resulting barcode depends on the type of data, so this is trapped later */ + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Detect extended ASCII characters */ + for(i = 0; i < sourcelen; i++) { + if(source[i] >= 128) + fset[i] = 'f'; + } + fset[i] = '\0'; + + /* Decide when to latch to extended mode - Annex E note 3 */ + j = 0; + for(i = 0; i < sourcelen; i++) { + if(fset[i] == 'f') { + j++; + } else { + j = 0; + } + + if(j >= 5) { + for(k = i; k > (i - 5); k--) { + fset[k] = 'F'; + } + } + + if((j >= 3) && (i == (sourcelen - 1))) { + for(k = i; k > (i - 3); k--) { + fset[k] = 'F'; + } + } + } + + /* Decide if it is worth reverting to 646 encodation for a few characters as described in 4.3.4.2 (d) */ + for(i = 1; i < sourcelen; i++) { + if((fset[i - 1] == 'F') && (fset[i] == ' ')) { + /* Detected a change from 8859-1 to 646 - count how long for */ + for(j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++); + if((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) { + /* Uses the same figures recommended by Annex E note 3 */ + /* Change to shifting back rather than latching back */ + for(k = 0; k < j; k++) { + fset[i + k] = 'n'; + } + } + } + } + + /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(source[indexchaine]); + if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { + mode = AORB; + } + + for(i = 0; i < 170; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < sourcelen)) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(source[indexchaine]); + if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { + mode = AORB; + } + } + indexliste++; + } while (indexchaine < sourcelen); + + dxsmooth(&indexliste); + + /* Resolve odd length LATCHC blocks */ + if((list[1][0] == LATCHC) && ((list[0][0] % 2) == 1)) { + /* Rule 2 */ + list[0][1]++; + list[0][0]--; + if(indexliste == 1) { + list[0][1] = 1; + list[1][1] = LATCHB; + indexliste = 2; + } + } + if(indexliste > 1) { + for(i = 1; i < indexliste; i++) { + if((list[1][i] == LATCHC) && ((list[0][i] % 2) == 1)) { + /* Rule 3b */ + list[0][i - 1]++; + list[0][i]--; + } + } + } + + /* Put set data into set[] */ + + read = 0; + for(i = 0; i < indexliste; i++) { + for(j = 0; j < list[0][i]; j++) { + switch(list[1][i]) { + case SHIFTA: set[read] = 'a'; break; + case LATCHA: set[read] = 'A'; break; + case SHIFTB: set[read] = 'b'; break; + case LATCHB: set[read] = 'B'; break; + case LATCHC: set[read] = 'C'; break; + } + read++; + } + } + + /* Adjust for strings which start with shift characters - make them latch instead */ + if(set[0] == 'a') { + i = 0; + 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 + being too long */ + last_set = ' '; + last_fset = ' '; + glyph_count = 0.0; + for(i = 0; i < sourcelen; i++) { + if((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if((fset[i] == 'f') || (fset[i] == 'n')) { + glyph_count = glyph_count + 1.0; + } + if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if(set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + if(i == 0) { + if(fset[i] == 'F') { + last_fset = 'F'; + glyph_count = glyph_count + 2.0; + } + } else { + if((fset[i] == 'F') && (fset[i - 1] != 'F')) { + last_fset = 'F'; + glyph_count = glyph_count + 2.0; + } + if((fset[i] != 'F') && (fset[i - 1] == 'F')) { + last_fset = ' '; + glyph_count = glyph_count + 2.0; + } + } + + if(set[i] == 'C') { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + if(glyph_count > 80.0) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + + /* So now we know what start character to use - we can get on with it! */ + if(symbol->output_options & READER_INIT) { + /* Reader Initialisation mode */ + switch(set[0]) { + case 'A': /* Start A */ + concat(dest, C128Table[103]); + values[0] = 103; + current_set = 'A'; + concat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + bar_characters++; + break; + case 'B': /* Start B */ + concat(dest, C128Table[104]); + values[0] = 104; + current_set = 'B'; + concat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + bar_characters++; + break; + case 'C': /* Start C */ + concat(dest, C128Table[104]); /* Start B */ + values[0] = 105; + concat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + concat(dest, C128Table[99]); /* Code C */ + values[2] = 99; + bar_characters += 2; + current_set = 'C'; + break; + } + } else { + /* Normal mode */ + switch(set[0]) { + case 'A': /* Start A */ + concat(dest, C128Table[103]); + values[0] = 103; + current_set = 'A'; + break; + case 'B': /* Start B */ + concat(dest, C128Table[104]); + values[0] = 104; + current_set = 'B'; + break; + case 'C': /* Start C */ + concat(dest, C128Table[105]); + values[0] = 105; + current_set = 'C'; + break; + } + } + bar_characters++; + last_set = set[0]; + + if(fset[0] == 'F') { + switch(current_set) { + case 'A': + concat(dest, C128Table[101]); + concat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + concat(dest, C128Table[100]); + concat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + + /* Encode the data */ + read = 0; + do { + + if((read != 0) && (set[read] != current_set)) + { /* Latch different code set */ + switch(set[read]) + { + case 'A': concat(dest, C128Table[101]); + values[bar_characters] = 101; + bar_characters++; + current_set = 'A'; + break; + case 'B': concat(dest, C128Table[100]); + values[bar_characters] = 100; + bar_characters++; + current_set = 'B'; + break; + case 'C': concat(dest, C128Table[99]); + values[bar_characters] = 99; + bar_characters++; + current_set = 'C'; + break; + } + } + + if(read != 0) { + if((fset[read] == 'F') && (f_state == 0)) { + /* Latch beginning of extended mode */ + switch(current_set) { + case 'A': + concat(dest, C128Table[101]); + concat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + concat(dest, C128Table[100]); + concat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + if((fset[read] == ' ') && (f_state == 1)) { + /* Latch end of extended mode */ + switch(current_set) { + case 'A': + concat(dest, C128Table[101]); + concat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + concat(dest, C128Table[100]); + concat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 0; + } + } + + if((fset[read] == 'f') || (fset[read] == 'n')) { + /* Shift to or from extended mode */ + switch(current_set) { + case 'A': + concat(dest, C128Table[101]); /* FNC 4 */ + values[bar_characters] = 101; + break; + case 'B': + concat(dest, C128Table[100]); /* FNC 4 */ + values[bar_characters] = 100; + break; + } + bar_characters++; + } + + if((set[read] == 'a') || (set[read] == 'b')) { + /* Insert shift character */ + concat(dest, C128Table[98]); + values[bar_characters] = 98; + bar_characters++; + } + + switch(set[read]) + { /* Encode data characters */ + case 'a': + case 'A': c128_set_a(source[read], dest, values, &bar_characters); + read++; + break; + case 'b': + case 'B': c128_set_b(source[read], dest, values, &bar_characters); + read++; + break; + case 'C': c128_set_c(source[read], source[read + 1], dest, values, &bar_characters); + read += 2; + break; + } + + } while (read < sourcelen); + + /* check digit calculation */ + total_sum = 0; + /*for(i = 0; i < bar_characters; i++) { + printf("%d\n", values[i]); + }*/ + + for(i = 0; i < bar_characters; i++) + { + if(i > 0) + { + values[i] *= i; + } + total_sum += values[i]; + } + concat(dest, C128Table[total_sum%103]); + + /* Stop character */ + concat(dest, C128Table[106]); + expand(symbol, dest); + return error_number; +} + +int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Handle EAN-128 (Now known as GS1-128) */ + int i, j, e_count, values[170], bar_characters, read, total_sum; + int error_number, indexchaine, indexliste; + char set[170], mode, last_set; + float glyph_count; + char dest[1000]; + int separator_row, linkage_flag, c_count; +#ifndef _MSC_VER + char reduced[length + 1]; +#else + char* reduced = (char*)_alloca(length + 1); +#endif + error_number = 0; + strcpy(dest, ""); + linkage_flag = 0; + + j = 0; + e_count = 0; + bar_characters = 0; + separator_row = 0; + + memset(values, 0, sizeof(values)); + memset(set, ' ', sizeof(set)); + + if(length > 160) { + /* This only blocks rediculously long input - the actual length of the + resulting barcode depends on the type of data, so this is trapped later */ + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + for(i = 0; i < length; i++) { + if(source[i] == '\0') { + /* Null characters not allowed! */ + strcpy(symbol->errtxt, "NULL character in input data"); + return ERROR_INVALID_DATA; + } + } + + /* if part of a composite symbol make room for the separator pattern */ + if(symbol->symbology == BARCODE_EAN128_CC) { + separator_row = symbol->rows; + symbol->row_height[symbol->rows] = 1; + symbol->rows += 1; + } + + if(symbol->input_mode != GS1_MODE) { + /* GS1 data has not been checked yet */ + error_number = gs1_verify(symbol, source, length, reduced); + if(error_number != 0) { return error_number; } + } + + /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(reduced[indexchaine]); + if(reduced[indexchaine] == '[') { + mode = ABORC; + } + + for(i = 0; i < 170; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < strlen(reduced))) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(reduced[indexchaine]); + if(reduced[indexchaine] == '[') { mode = ABORC; } + } + indexliste++; + } while (indexchaine < strlen(reduced)); + + dxsmooth(&indexliste); + + /* Put set data into set[] */ + read = 0; + for(i = 0; i < indexliste; i++) { + for(j = 0; j < list[0][i]; j++) { + switch(list[1][i]) { + case SHIFTA: set[read] = 'a'; break; + case LATCHA: set[read] = 'A'; break; + case SHIFTB: set[read] = 'b'; break; + case LATCHB: set[read] = 'B'; break; + case LATCHC: set[read] = 'C'; break; + } + read++; + } + } + + /* Watch out for odd-length Mode C blocks */ + c_count = 0; + for(i = 0; i < read; i++) { + if(set[i] == 'C') { + if(reduced[i] == '[') { + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } else { + c_count++; + } + } else { + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } + } + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + for(i = 1; i < read - 1; i++) { + if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { + set[i] = 'B'; + } + } + + /* for(i = 0; i < read; i++) { + printf("char %c mode %c\n", reduced[i], set[i]); + } */ + + /* Now we can calculate how long the barcode is going to be - and stop it from + being too long */ + last_set = ' '; + glyph_count = 0.0; + for(i = 0; i < strlen(reduced); i++) { + if((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if(set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + + if((set[i] == 'C') && (reduced[i] != '[')) { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + if(glyph_count > 80.0) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* So now we know what start character to use - we can get on with it! */ + switch(set[0]) + { + case 'A': /* Start A */ + concat(dest, C128Table[103]); + values[0] = 103; + break; + case 'B': /* Start B */ + concat(dest, C128Table[104]); + values[0] = 104; + break; + case 'C': /* Start C */ + concat(dest, C128Table[105]); + values[0] = 105; + break; + } + bar_characters++; + + concat(dest, C128Table[102]); + values[1] = 102; + bar_characters++; + + /* Encode the data */ + read = 0; + do { + + if((read != 0) && (set[read] != set[read - 1])) + { /* Latch different code set */ + switch(set[read]) + { + case 'A': concat(dest, C128Table[101]); + values[bar_characters] = 101; + bar_characters++; + break; + case 'B': concat(dest, C128Table[100]); + values[bar_characters] = 100; + bar_characters++; + break; + case 'C': concat(dest, C128Table[99]); + values[bar_characters] = 99; + bar_characters++; + break; + } + } + + if((set[read] == 'a') || (set[read] == 'b')) { + /* Insert shift character */ + concat(dest, C128Table[98]); + values[bar_characters] = 98; + bar_characters++; + } + + if(reduced[read] != '[') { + switch(set[read]) + { /* Encode data characters */ + case 'A': + case 'a': + c128_set_a(reduced[read], dest, values, &bar_characters); + read++; + break; + case 'B': + case 'b': + c128_set_b(reduced[read], dest, values, &bar_characters); + read++; + break; + case 'C': + c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters); + read += 2; + break; + } + } else { + concat(dest, C128Table[102]); + values[bar_characters] = 102; + bar_characters++; + read++; + } + } while (read < strlen(reduced)); + + /* "...note that the linkage flag is an extra code set character between + the last data character and the Symbol Check Character" (GS1 Specification) */ + + /* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */ + + switch(symbol->option_1) { + case 1: + case 2: + /* CC-A or CC-B 2D component */ + switch(set[strlen(reduced) - 1]) { + case 'A': linkage_flag = 100; break; + case 'B': linkage_flag = 99; break; + case 'C': linkage_flag = 101; break; + } + break; + case 3: + /* CC-C 2D component */ + switch(set[strlen(reduced) - 1]) { + case 'A': linkage_flag = 99; break; + case 'B': linkage_flag = 101; break; + case 'C': linkage_flag = 100; break; + } + break; + } + + if(linkage_flag != 0) { + concat(dest, C128Table[linkage_flag]); + values[bar_characters] = linkage_flag; + bar_characters++; + } + + /*for(i = 0; i < bar_characters; i++) { + printf("[%d] ", values[i]); + } + printf("\n");*/ + + /* check digit calculation */ + total_sum = 0; + for(i = 0; i < bar_characters; i++) + { + if(i > 0) + { + values[i] *= i; + + } + total_sum += values[i]; + } + concat(dest, C128Table[total_sum%103]); + values[bar_characters] = total_sum % 103; + bar_characters++; + + /* Stop character */ + concat(dest, C128Table[106]); + values[bar_characters] = 106; + bar_characters++; + expand(symbol, dest); + + /* Add the separator pattern for composite symbols */ + if(symbol->symbology == BARCODE_EAN128_CC) { + for(i = 0; i < symbol->width; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + } + + for(i = 0; i < length; i++) { + if((source[i] != '[') && (source[i] != ']')) { + symbol->text[i] = source[i]; + } + if(source[i] == '[') { + symbol->text[i] = '('; + } + if(source[i] == ']') { + symbol->text[i] = ')'; + } + } + + return error_number; +} + +int nve_18(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Add check digit if encoding an NVE18 symbol */ + int error_number, zeroes, i, nve_check, total_sum, sourcelen; + unsigned char ean128_equiv[25]; + + memset(ean128_equiv, 0, 25); + sourcelen = length; + + if(sourcelen > 17) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + zeroes = 17 - sourcelen; + strcpy((char *)ean128_equiv, "[00]"); + memset(ean128_equiv + 4, '0', zeroes); + strcpy((char*)ean128_equiv + 4 + zeroes, (char*)source); + + total_sum = 0; + for(i = sourcelen - 1; i >= 0; i--) + { + total_sum += ctoi(source[i]); + + if(!((i%2) == 1)) { + total_sum += 2 * ctoi(source[i]); + } + } + nve_check = 10 - total_sum % 10; + if(nve_check == 10) { nve_check = 0; } + ean128_equiv[21] = itoc(nve_check); + ean128_equiv[22] = '\0'; + + error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + + return error_number; +} + +int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* EAN-14 - A version of EAN-128 */ + int i, count, check_digit; + int error_number, zeroes; + unsigned char ean128_equiv[20]; + + if(length > 13) { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid character in data"); + return error_number; + } + + zeroes = 13 - length; + strcpy((char*)ean128_equiv, "[01]"); + memset(ean128_equiv + 4, '0', zeroes); + ustrcpy(ean128_equiv + 4 + zeroes, source); + + count = 0; + for (i = length - 1; i >= 0; i--) + { + count += ctoi(source[i]); + + if (!((i % 2) == 1)) + { + count += 2 * ctoi(source[i]); + } + } + check_digit = 10 - (count % 10); + if (check_digit == 10) { check_digit = 0; } + ean128_equiv[17] = itoc(check_digit); + ean128_equiv[18] = '\0'; + + error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + + return error_number; +} diff --git a/backend/code16k.c b/backend/code16k.c new file mode 100644 index 00000000..8697601d --- /dev/null +++ b/backend/code16k.c @@ -0,0 +1,622 @@ +/* code16k.c - Handles Code 16k stacked symbology */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* Updated to comply with BS EN 12323:2005 */ + +/* up to 77 characters or 154 numbers */ + +#include +#include +#include +#include "common.h" + +#define TRUE 1 +#define FALSE 0 +#define SHIFTA 90 +#define LATCHA 91 +#define SHIFTB 92 +#define LATCHB 93 +#define SHIFTC 94 +#define LATCHC 95 +#define AORB 96 +#define ABORC 97 +#define CANDB 98 +#define CANDBB 99 + +static int list[2][170]; + +/* EN 12323 Table 1 - "Code 16K" character encodations */ +static char *C16KTable[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213", + "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", + "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", + "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", + "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", + "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", + "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", + "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", + "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", + "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", + "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", + "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", + "211133"}; + +/* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */ +static char *C16KStartStop[8] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "3112"}; + +/* EN 12323 Table 5 - Start and stop values defining row numbers */ +static int C16KStartValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}; +static int C16KStopValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3}; + +void grwp16(int *indexliste) +{ + int i, j; + + /* bring together same type blocks */ + if(*(indexliste) > 1) { + i = 1; + while(i < *(indexliste)) { + if(list[1][i - 1] == list[1][i]) { + /* bring together */ + list[0][i - 1] = list[0][i - 1] + list[0][i]; + j = i + 1; + + /* decreace the list */ + while(j < *(indexliste)) { + list[0][j - 1] = list[0][j]; + list[1][j - 1] = list[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } +} + +void dxsmooth16(int *indexliste) +{ /* Implements rules from ISO 15417 Annex E */ + int i, current, last, next, length; + + for(i = 0; i < *(indexliste); i++) { + current = list[1][i]; + length = list[0][i]; + if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; } + if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; } + + if(i == 0) { /* first block */ + if((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; } + if(current == ABORC) { + if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; 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) { /* Rule 1d */ list[1][i] = LATCHB; } + } else { + if((current == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; current = LATCHC; } + if(current == ABORC) { list[1][i] = AORB; current = AORB; } + if((current == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } + 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) { list[1][i] = LATCHB; current = LATCHB; } + if((current == SHIFTA) && (length > 1)) { /* 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 */ + } + grwp16(indexliste); + +} + +void c16k_set_a(unsigned char source, unsigned int values[], unsigned int *bar_chars) +{ + if(source > 127) { + if(source < 160) { + values[(*bar_chars)] = source + 64 - 128; + } else { + values[(*bar_chars)] = source - 32 - 128; + } + } else { + if(source < 32) { + values[(*bar_chars)] = source + 64; + } else { + values[(*bar_chars)] = source - 32; + } + } + (*bar_chars)++; +} + +void c16k_set_b(unsigned char source, unsigned int values[], unsigned int *bar_chars) +{ + if(source > 127) { + values[(*bar_chars)] = source - 32 - 128; + } else { + values[(*bar_chars)] = source - 32; + } + (*bar_chars)++; +} + +void c16k_set_c(unsigned char source_a, unsigned char source_b, unsigned int values[], unsigned int *bar_chars) +{ + int weight; + + weight = (10 * ctoi(source_a)) + ctoi(source_b); + values[(*bar_chars)] = weight; + (*bar_chars)++; +} + +int code16k(struct zint_symbol *symbol, unsigned char source[], int length) +{ + char width_pattern[100]; + int current_row, rows_needed, flip_flop, looper, first_check, second_check; + int indexliste, indexchaine, pads_needed, f_state; + char set[160] = { ' ' }, fset[160] = { ' ' }, mode, last_set, last_fset, current_set; + unsigned int i, j, k, m, e_count, read, mx_reader, writer; + unsigned int values[160] = { 0 }; + unsigned int bar_characters; + float glyph_count; + int errornum, first_sum, second_sum; + int input_length; + int gs1, c_count; + + errornum = 0; + strcpy(width_pattern, ""); + input_length = length; + + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + + if(input_length > 157) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + e_count = 0; + bar_characters = 0; + + /* Detect extended ASCII characters */ + for(i = 0; i < input_length; i++) { + if(source[i] >=128) { + fset[i] = 'f'; + } + } + fset[i] = '\0'; + + /* Decide when to latch to extended mode */ + for(i = 0; i < input_length; i++) { + j = 0; + if(fset[i] == 'f') { + do { + j++; + } while(fset[i + j] == 'f'); + if((j >= 5) || ((j >= 3) && ((i + j) == (input_length - 1)))) { + for(k = 0; k <= j; k++) { + fset[i + k] = 'F'; + } + } + } + } + + /* Decide if it is worth reverting to 646 encodation for a few characters */ + if(input_length > 1) { + for(i = 1; i < input_length; i++) { + if((fset[i - 1] == 'F') && (fset[i] == ' ')) { + /* Detected a change from 8859-1 to 646 - count how long for */ + for(j = 0; (fset[i + j] == ' ') && ((i + j) < input_length); j++); + if((j < 5) || ((j < 3) && ((i + j) == (input_length - 1)))) { + /* Change to shifting back rather than latching back */ + for(k = 0; k < j; k++) { + fset[i + k] = 'n'; + } + } + } + } + } + /* Detect mode A, B and C characters */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(source[indexchaine]); + if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ + + for(i = 0; i < 160; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < input_length)) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(source[indexchaine]); + if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ + } + indexliste++; + } while (indexchaine < input_length); + + dxsmooth16(&indexliste); + + /* Put set data into set[] */ + read = 0; + for(i = 0; i < indexliste; i++) { + for(j = 0; j < list[0][i]; j++) { + switch(list[1][i]) { + case SHIFTA: set[read] = 'a'; break; + case LATCHA: set[read] = 'A'; break; + case SHIFTB: set[read] = 'b'; break; + case LATCHB: set[read] = 'B'; break; + case LATCHC: set[read] = 'C'; break; + } + read++; + } + } + + /* Adjust for strings which start with shift characters - make them latch instead */ + if(set[0] == 'a') { + i = 0; + do { + set[i] = 'A'; + i++; + } while (set[i] == 'a'); + } + + if(set[0] == 'b') { + i = 0; + do { + set[i] = 'B'; + i++; + } while (set[i] == 'b'); + } + + /* Watch out for odd-length Mode C blocks */ + c_count = 0; + for(i = 0; i < read; i++) { + if(set[i] == 'C') { + if(source[i] == '[') { + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } else { + c_count++; + } + } else { + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } + } + if(c_count % 2) { + if((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + for(i = 1; i < read - 1; i++) { + if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { + set[i] = 'B'; + } + } + + /* Make sure the data will fit in the symbol */ + last_set = ' '; + last_fset = ' '; + glyph_count = 0.0; + for(i = 0; i < input_length; i++) { + if((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if((fset[i] == 'f') || (fset[i] == 'n')) { + glyph_count = glyph_count + 1.0; + } + if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if(set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + if(i == 0) { + if((set[i] == 'B') && (set[1] == 'C')) { + glyph_count = glyph_count - 1.0; + } + if((set[i] == 'B') && (set[1] == 'B')) { + if(set[2] == 'C') { + glyph_count = glyph_count - 1.0; + } + } + if(fset[i] == 'F') { + last_fset = 'F'; + glyph_count = glyph_count + 2.0; + } + } else { + if((fset[i] == 'F') && (fset[i - 1] != 'F')) { + last_fset = 'F'; + glyph_count = glyph_count + 2.0; + } + if((fset[i] != 'F') && (fset[i - 1] == 'F')) { + last_fset = ' '; + glyph_count = glyph_count + 2.0; + } + } + + if((set[i] == 'C') && (!((gs1) && (source[i] == '[')))) { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + + if((gs1) && (set[0] != 'A')) { + /* FNC1 can be integrated with mode character */ + glyph_count--; + } + + if(glyph_count > 77.0) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Calculate how tall the symbol will be */ + glyph_count = glyph_count + 2.0; + i = glyph_count; + rows_needed = (i/5); + if(i%5 > 0) { rows_needed++; } + + if(rows_needed == 1) { + rows_needed = 2; + } + + /* start with the mode character - Table 2 */ + m = 0; + switch(set[0]) { + case 'A': m = 0; break; + case 'B': m = 1; break; + case 'C': m = 2; break; + } + + if(symbol->output_options & READER_INIT) { + if(m == 2) { m = 5; } + if(gs1) { + strcpy(symbol->errtxt, "Cannot use both GS1 mode and Reader Initialisation"); + return ERROR_INVALID_OPTION; + } else { + if((set[0] == 'B') && (set[1] == 'C')) { m = 6; } + } + values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ + values[bar_characters + 1] = 96; /* FNC3 */ + bar_characters += 2; + } else { + if(gs1) { + /* Integrate FNC1 */ + switch(set[0]) { + case 'B': m = 3; break; + case 'C': m = 4; break; + } + } else { + if((set[0] == 'B') && (set[1] == 'C')) { m = 5; } + if(((set[0] == 'B') && (set[1] == 'B')) && (set[2] == 'C')) { m = 6; } + } + values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ + bar_characters++; + } + + current_set = set[0]; + f_state = 0; /* f_state remembers if we are in Extended ASCII mode (value 1) or + in ISO/IEC 646 mode (value 0) */ + if(fset[0] == 'F') { + switch(current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + + read = 0; + + /* Encode the data */ + do { + + if((read != 0) && (set[read] != set[read - 1])) + { /* Latch different code set */ + switch(set[read]) + { + case 'A': + values[bar_characters] = 101; + bar_characters++; + current_set = 'A'; + break; + case 'B': + values[bar_characters] = 100; + bar_characters++; + current_set = 'B'; + break; + case 'C': + if(!((read == 1) && (set[0] == 'B'))) { /* Not Mode C/Shift B */ + if(!((read == 2) && ((set[0] == 'B') && (set[1] == 'B')))) { + /* Not Mode C/Double Shift B */ + values[bar_characters] = 99; + bar_characters++; + } + } + current_set = 'C'; + break; + } + } + /* printf("tp8\n"); */ + if(read != 0) { + if((fset[read] == 'F') && (f_state == 0)) { + /* Latch beginning of extended mode */ + switch(current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + if((fset[read] == ' ') && (f_state == 1)) { + /* Latch end of extended mode */ + switch(current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 0; + } + } + + if((fset[i] == 'f') || (fset[i] == 'n')) { + /* Shift extended mode */ + switch(current_set) { + case 'A': + values[bar_characters] = 101; /* FNC 4 */ + break; + case 'B': + values[bar_characters] = 100; /* FNC 4 */ + break; + } + bar_characters++; + } + + if((set[i] == 'a') || (set[i] == 'b')) { + /* Insert shift character */ + values[bar_characters] = 98; + bar_characters++; + } + + if(!((gs1) && (source[read] == '['))) { + switch(set[read]) + { /* Encode data characters */ + case 'A': + case 'a': + c16k_set_a(source[read], values, &bar_characters); + read++; + break; + case 'B': + case 'b': + c16k_set_b(source[read], values, &bar_characters); + read++; + break; + case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters); + read += 2; + break; + } + } else { + values[bar_characters] = 102; + bar_characters++; + read++; + } + /* printf("tp9 read=%d surrent set=%c\n", read, set[read]); */ + } while (read < ustrlen(source)); + + pads_needed = 5 - ((bar_characters + 2) % 5); + if(pads_needed == 5) { + pads_needed = 0; + } + if((bar_characters + pads_needed) < 8) { + pads_needed += 8 - (bar_characters + pads_needed); + } + for(i = 0; i < pads_needed; i++) { + values[bar_characters] = 106; + bar_characters++; + } + + /* Calculate check digits */ + first_sum = 0; + second_sum = 0; + for(i = 0; i < bar_characters; i++) + { + first_sum += (i+2) * values[i]; + second_sum += (i+1) * values[i]; + } + first_check = first_sum % 107; + second_sum += first_check * (bar_characters + 1); + second_check = second_sum % 107; + values[bar_characters] = first_check; + values[bar_characters + 1] = second_check; + bar_characters += 2; + + for(current_row = 0; current_row < rows_needed; current_row++) { + + strcpy(width_pattern, ""); + concat(width_pattern, C16KStartStop[C16KStartValues[current_row]]); + concat(width_pattern, "1"); + for(i = 0; i < 5; i++) { + concat(width_pattern, C16KTable[values[(current_row * 5) + i]]); + /* printf("[%d] ", values[(current_row * 5) + i]); */ + + } + concat(width_pattern, C16KStartStop[C16KStopValues[current_row]]); + /* printf("\n"); */ + + /* Write the information into the symbol */ + writer = 0; + flip_flop = 1; + for (mx_reader = 0; mx_reader < strlen(width_pattern); mx_reader++) { + for(looper = 0; looper < ctoi(width_pattern[mx_reader]); looper++) { + if(flip_flop == 1) { + set_module(symbol, current_row, writer); + writer++; } + else { + writer++; } + } + if(flip_flop == 0) { flip_flop = 1; } else { flip_flop = 0; } + } + symbol->row_height[current_row] = 10; + } + + symbol->rows = rows_needed; + symbol->width = 70; + return errornum; +} + + diff --git a/backend/code49.c b/backend/code49.c new file mode 100644 index 00000000..74883b08 --- /dev/null +++ b/backend/code49.c @@ -0,0 +1,315 @@ +/* code49.c - Handles Code 49 */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include "common.h" +#include "code49.h" + +#define INSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%!&*" +/* "!" represents Shift 1 and "&" represents Shift 2, "*" represents FNC1 */ + +int code_49(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int i, j, rows, M, x_count, y_count, z_count, posn_val, local_value, h; + char intermediate[170]; + int codewords[170], codeword_count; + int c_grid[8][8]; /* Refers to table 3 */ + int w_grid[8][4]; /* Refets to table 2 */ + int pad_count = 0; + char pattern[40]; + int gs1; + + if(length > 81) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + + strcpy(intermediate, gs1 ? "*" : ""); /* FNC1 */ + for(i = 0; i < length; i++) { + if(source[i] > 127) { + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + if(gs1 && (source[i] == '[')) + concat(intermediate, "*"); /* FNC1 */ + else + concat(intermediate, c49_table7[source[i]]); + } + + codeword_count = 0; + i = 0; + h = strlen(intermediate); + do { + if((intermediate[i] >= '0') && (intermediate[i] <= '9')) { + /* Numeric data */ + for(j = 0; (intermediate[i + j] >= '0') && (intermediate[i + j] <= '9'); j++); + if(j >= 5) { + /* Use Numeric Encodation Method */ + int block_count, c; + int block_remain; + int block_value; + + codewords[codeword_count] = 48; /* Numeric Shift */ + codeword_count++; + + block_count = j / 5; + block_remain = j % 5; + + for(c = 0; c < block_count; c++) { + if((c == block_count - 1) && (block_remain == 2)) { + /* Rule (d) */ + block_value = 100000; + block_value += ctoi(intermediate[i]) * 1000; + block_value += ctoi(intermediate[i + 1]) * 100; + block_value += ctoi(intermediate[i + 2]) * 10; + block_value += ctoi(intermediate[i + 3]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 4; + block_value = ctoi(intermediate[i]) * 100; + block_value += ctoi(intermediate[i + 1]) * 10; + block_value += ctoi(intermediate[i + 2]); + + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 3; + } else { + block_value = ctoi(intermediate[i]) * 10000; + block_value += ctoi(intermediate[i + 1]) * 1000; + block_value += ctoi(intermediate[i + 2]) * 100; + block_value += ctoi(intermediate[i + 3]) * 10; + block_value += ctoi(intermediate[i + 4]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 5; + } + } + + switch(block_remain) { + case 1: + /* Rule (a) */ + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + break; + case 3: + /* Rule (b) */ + block_value = ctoi(intermediate[i]) * 100; + block_value += ctoi(intermediate[i + 1]) * 10; + block_value += ctoi(intermediate[i + 2]); + + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 3; + break; + case 4: + /* Rule (c) */ + block_value = 100000; + block_value += ctoi(intermediate[i]) * 1000; + block_value += ctoi(intermediate[i + 1]) * 100; + block_value += ctoi(intermediate[i + 2]) * 10; + block_value += ctoi(intermediate[i + 3]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 4; + break; + } + if(i < h) { + /* There is more to add */ + codewords[codeword_count] = 48; /* Numeric Shift */ + codeword_count++; + } + } else { + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + } + } else { + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + } + } while(i < h); + + switch(codewords[0]) { /* Set starting mode value */ + case 48: M = 2; + case 43: M = 4; + case 44: M = 5; + default: M = 0; + } + + if(M != 0) { + for(i = 0; i < codeword_count; i++) { + codewords[i] = codewords[i + 1]; + } + codeword_count--; + } + + if(codeword_count > 49) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Place codewords in code character array (c grid) */ + rows = 0; + do{ + for(i = 0; i < 7; i++) { + if(((rows * 7) + i) < codeword_count) { + c_grid[rows][i] = codewords[(rows * 7) + i]; + } else { + c_grid[rows][i] = 48; /* Pad */ + pad_count++; + } + } + rows++; + } while ((rows * 7) < codeword_count); + + if((((rows <= 6) && (pad_count < 5))) || (rows > 6) || (rows == 1)) { + /* Add a row */ + for(i = 0; i < 7; i++) { + c_grid[rows][i] = 48; /* Pad */ + } + rows++; + } + + /* Add row count and mode character */ + c_grid[rows - 1][6] = (7 * (rows - 2)) + M; + + /* Add row check character */ + for(i = 0; i < rows - 1; i++) { + int row_sum = 0; + + for(j = 0; j < 7; j++) { + row_sum += c_grid[i][j]; + } + c_grid[i][7] = row_sum % 49; + } + + /* Calculate Symbol Check Characters */ + posn_val = 0; + x_count = c_grid[rows - 1][6] * 20; + y_count = c_grid[rows - 1][6] * 16; + z_count = c_grid[rows - 1][6] * 38; + for(i = 0; i < rows - 1; i++) { + for(j = 0; j < 4; j++) { + local_value = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; + x_count += c49_x_weight[posn_val] * local_value; + y_count += c49_y_weight[posn_val] * local_value; + z_count += c49_z_weight[posn_val] * local_value; + posn_val++; + } + } + + if(rows > 6) { + /* Add Z Symbol Check */ + c_grid[rows - 1][0] = (z_count % 2401) / 49; + c_grid[rows - 1][1] = (z_count % 2401) % 49; + } + + local_value = (c_grid[rows - 1][0] * 49) + c_grid[rows - 1][1]; + x_count += c49_x_weight[posn_val] * local_value; + y_count += c49_y_weight[posn_val] * local_value; + posn_val++; + + /* Add Y Symbol Check */ + c_grid[rows - 1][2] = (y_count % 2401) / 49; + c_grid[rows - 1][3] = (y_count % 2401) % 49; + + local_value = (c_grid[rows - 1][2] * 49) + c_grid[rows - 1][3]; + x_count += c49_x_weight[posn_val] * local_value; + + /* Add X Symbol Check */ + c_grid[rows - 1][4] = (x_count % 2401) / 49; + c_grid[rows - 1][5] = (x_count % 2401) % 49; + + /* Add last row check character */ + j = 0; + for(i = 0; i < 7; i++) { + j += c_grid[rows - 1][i]; + } + c_grid[rows - 1][7] = j % 49; + + /* Transfer data to symbol character array (w grid) */ + for(i = 0; i < rows; i++) { + for(j = 0; j < 4; j ++) { + w_grid[i][j] = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; + } + } + + for(i = 0; i < rows; i++) { + strcpy(pattern, "11"); /* Start character */ + for(j = 0; j < 4; j++) { + if(i != (rows - 1)) { + if(c49_table4[i][j] == 'E') { + /* Even Parity */ + concat(pattern, c49_appxe_even[w_grid[i][j]]); + } else { + /* Odd Parity */ + concat(pattern, c49_appxe_odd[w_grid[i][j]]); + } + } else { + /* Last row uses all even parity */ + concat(pattern, c49_appxe_even[w_grid[i][j]]); + } + } + concat(pattern, "4"); /* Stop character */ + + /* Expand into symbol */ + symbol->row_height[i] = 10; + expand(symbol, pattern); + } + + symbol->whitespace_width = 10; + symbol->output_options = BARCODE_BIND; + symbol->border_width = 2; + + return 0; +} \ No newline at end of file diff --git a/backend/code49.h b/backend/code49.h new file mode 100644 index 00000000..2b27bc1b --- /dev/null +++ b/backend/code49.h @@ -0,0 +1,1175 @@ +/* code49.h - Code 49 Tables */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +/* This data set taken from ANSI/AIM-BC6-2000, 4th April 2000 */ + +static char *c49_table7[128] = { + /* Table 7: Code 49 ASCII Chart */ + "! ", "!A", "!B", "!C", "!D", "!E", "!F", "!G", "!H", "!I", "!J", "!K", "!L", + "!M", "!N", "!O", "!P", "!Q", "!R", "!S", "!T", "!U", "!V", "!W", "!X", "!Y", + "!Z", "!1", "!2", "!3", "!4", "!5", " ", "!6", "!7", "!8", "$", "%", "!9", "!0", + "!-", "!.", "!$", "+", "!/", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "!+", "&1", "&2", "&3", "&4", "&5", "&6", "A", "B", "C", "D", "E", + "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", "&7", "&8", "&9", "&0", "&-", "&.", "&A", "&B", "&C", + "&D", "&E", "&F", "&G", "&H", "&I", "&J", "&K", "&L", "&M", "&N", "&O", "&P", + "&Q", "&R", "&S", "&T", "&U", "&V", "&W", "&X", "&Y", "&Z", "&$", "&/", "&+", + "&%", "& " +}; + +/* Table 5: Check Character Weighting Values */ +int c49_x_weight[] = { + 1, 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, + 39, 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10 +}; + +int c49_y_weight[] = { + 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, + 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24 +}; + +int c49_z_weight[] = { + 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, 11, + 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24, 30 +}; + +static char *c49_table4[8] = { + /* Table 4: Row Parity Pattern for Code 49 Symbols */ + "OEEO", "EOEO", "OOEE", "EEOO", "OEOE", "EOOE", "OOOO", "EEEE" +}; + +static char *c49_appxe_even[2401] = { + /* Appendix E - Code 49 Encodation Patterns (Even Symbol Character Parity) */ + /* Column 1 */ + "11521132", + "25112131", "14212132", "25121221", "14221222", "12412132", + "23321221", "12421222", "21521221", "15112222", "15121312", + "13312222", "24221311", "13321312", "11512222", "22421311", + "11521312", "25112311", "14212312", "23312311", "12412312", + "21512311", "16121131", "14321131", "12521131", "15212131", + "15221221", "13412131", "13421221", "11612131", "16112221", + "16121311", "14312221", "14321311", "12512221", "12521311", + "15212311", "13412311", "11612311", "11131135", "31131133", + "51131131", "21122134", "41122132", "21131224", "41131222", + "11113135", "31113133", "51113131", "11122225", "31122223", + "51122221", "11131315", "31131313", "51131311", "21113224", + "41113222", "21122314", + /* Column 2 */ + "41122312", "11113315", "31113313", + "51113311", "12131134", "32131132", "21231133", "41231131", + "22122133", "42122131", "11222134", "22131223", "42131221", + "11231224", "31231222", "12113134", "32113132", "12122224", + "32122222", "12131314", "32131312", "21231313", "41231311", + "22113223", "42113221", "11213224", "22122313", "42122311", + "11222314", "31222312", "12113314", "32113312", "21213313", + "41213311", "13131133", "33131131", "22231132", "11331133", + "31331131", "23122132", "12222133", "23131222", "12231223", + "32231221", "21331222", "13113133", "33113131", "13122223", + "33122221", "11313133", "13131313", "33131311", "11322223", + "22231312", "11331313", "31331311", "23113222", "12213223", + /* Column 3 */ + "23122312", "12222313", "32222311", "21322312", "13113313", + "33113311", "22213312", "11313313", "31313311", "14131132", + "23231131", "12331132", "21431131", "24122131", "13222132", + "24131221", "13231222", "11422132", "22331221", "11431222", + "14113132", "14122222", "12313132", "14131312", "12322222", + "23231311", "12331312", "21431311", "24113221", "13213222", + "24122311", "13222312", "11413222", "22322311", "11422312", + "14113312", "23213311", "12313312", "21413311", "15131131", + "13331131", "14222131", "14231221", "12422131", "12431221", + "15113131", "15122221", "13313131", "15131311", "13322221", + "11513131", "13331311", "11522221", "14213221", "14222311", + "12413221", "12422311", "15113311", + /* Column 4 */ + "13313311", "11513311", + "11141134", "31141132", "21132133", "41132131", "21141223", + "41141221", "11123134", "31123132", "11132224", "31132222", + "11141314", "31141312", "21114133", "41114131", "21123223", + "41123221", "21132313", "41132311", "11114224", "31114222", + "11123314", "31123312", "21114313", "41114311", "12141133", + "32141131", "21241132", "22132132", "11232133", "22141222", + "11241223", "31241221", "12123133", "32123131", "12132223", + "32132221", "12141313", "32141311", "21241312", "22114132", + "11214133", "22123222", "11223223", "22132312", "11232313", + "31232311", "12114223", "32114221", "12123313", "32123311", + "21223312", "22114312", "11214313", "31214311", "13141132", + "22241131", + /* Column 5 */ + "11341132", "23132131", "12232132", "23141221", + "12241222", "21341221", "13123132", "13132222", "11323132", + "13141312", "11332222", "22241311", "11341312", "23114131", + "12214132", "23123221", "12223222", "23132311", "12232312", + "21332311", "13114222", "13123312", "11314222", "22223311", + "11323312", "23114311", "12214312", "21314311", "14141131", + "12341131", "13232131", "13241221", "11432131", "14123131", + "14132221", "12323131", "14141311", "12332221", "12341311", + "13214131", "13223221", "11414131", "13232311", "11423221", + "11432311", "14114221", "14123311", "12314221", "12323311", + "13214311", "11414311", "11151133", "31151131", "21142132", + "21151222", "11133133", "31133131", "11142223", + /* Column 6 */ + "31142221", + "11151313", "31151311", "21124132", "21133222", "21142312", + "11115133", "31115131", "11124223", "31124221", "11133313", + "31133311", "21115222", "21124312", "12151132", "21251131", + "22142131", "11242132", "22151221", "11251222", "12133132", + "12142222", "12151312", "21251311", "22124131", "11224132", + "22133221", "11233222", "22142311", "11242312", "12115132", + "12124222", "12133312", "21233311", "22115221", "11215222", + "22124311", "11224312", "13151131", "12242131", "12251221", + "13133131", "13142221", "11333131", "13151311", "11342221", + "12224131", "12233221", "12242311", "13115131", "13124221", + "11315131", "13133311", "11324221", "11333311", "12215221", + "12224311", "11161132", + /* Column 7 */ + "21152131", "21161221", "11143132", + "11152222", "11161312", "21134131", "21143221", "21152311", + "11125132", "11134222", "11143312", "21116131", "21125221", + "21134311", "12161131", "11252131", "12143131", "12152221", + "12161311", "11234131", "11243221", "11252311", "12125131", + "12134221", "12143311", "11216131", "11225221", "11234311", + "11111236", "31111234", "51111232", "21111325", "41111323", + "61111321", "11111416", "31111414", "51111412", "31211143", + "51211141", "12111235", "32111233", "52111231", "21211234", + "41211232", "22111324", "42111322", "11211325", "31211323", + "51211321", "12111415", "32111413", "52111411", "21211414", + "41211412", "12211144", "32211142", "21311143", "41311141", + /* Column 8 */ + "13111234", "33111232", "22211233", "42211231", "11311234", + "31311232", "23111323", "43111321", "12211324", "32211322", + "21311323", "41311321", "13111414", "33111412", "22211413", + "42211411", "11311414", "31311412", "13211143", "33211141", + "22311142", "11411143", "31411141", "14111233", "34111231", + "23211232", "12311233", "32311231", "21411232", "24111322", + "13211323", "33211321", "22311322", "11411323", "31411321", + "14111413", "34111411", "23211412", "12311413", "32311411", + "21411412", "14211142", "23311141", "12411142", "21511141", + "15111232", "24211231", "13311232", "22411231", "11511232", + "25111321", "14211322", "23311321", "12411322", "21511321", + "15111412", "24211411", "13311412", + /* Column 9 */ + "22411411", "11511412", + "15211141", "13411141", "11611141", "16111231", "14311231", + "12511231", "15211321", "13411321", "11611321", "16111411", + "14311411", "12511411", "21121144", "41121142", "11112145", + "31112143", "51112141", "11121235", "31121233", "51121231", + "21112234", "41112232", "21121324", "41121322", "11112325", + "31112323", "51112321", "11121415", "31121413", "51121411", + "21112414", "41112412", "22121143", "42121141", "11221144", + "31221142", "12112144", "32112142", "12121234", "32121232", + "21221233", "41221231", "22112233", "42112231", "11212234", + "22121323", "42121321", "11221324", "31221322", "12112324", + "32112322", "12121414", "32121412", "21221413", "41221411", + "22112413", + /* Column 10 */ + "42112411", "11212414", "31212412", "23121142", + "12221143", "32221141", "21321142", "13112143", "33112141", + "13121233", "33121231", "11312143", "22221232", "11321233", + "31321231", "23112232", "12212233", "23121322", "12221323", + "32221321", "21321322", "13112323", "33112321", "13121413", + "33121411", "11312323", "22221412", "11321413", "31321411", + "23112412", "12212413", "32212411", "21312412", "24121141", + "13221142", "22321141", "11421142", "14112142", "14121232", + "12312142", "23221231", "12321232", "21421231", "24112231", + "13212232", "24121321", "13221322", "11412232", "22321321", + "11421322", "14112322", "14121412", "12312322", "23221411", + "12321412", "21421411", "24112411", "13212412", + /* Column 11 */ + "22312411", + "11412412", "14221141", "12421141", "15112141", "15121231", + "13312141", "13321231", "11512141", "11521231", "14212231", + "14221321", "12412231", "12421321", "15112321", "15121411", + "13312321", "13321411", "11512321", "11521411", "14212411", + "12412411", "21131143", "41131141", "11122144", "31122142", + "11131234", "31131232", "21113143", "41113141", "21122233", + "41122231", "21131323", "41131321", "11113234", "31113232", + "11122324", "31122322", "11131414", "31131412", "21113323", + "41113321", "21122413", "41122411", "11113414", "31113412", + "22131142", "11231143", "31231141", "12122143", "32122141", + "12131233", "32131231", "21231232", "22113142", "11213143", + "22122232", "11222233", + /* Column 12 */ + "22131322", "11231323", "31231321", + "12113233", "32113231", "12122323", "32122321", "12131413", + "32131411", "21231412", "22113322", "11213323", "22122412", + "11222413", "31222411", "12113413", "32113411", "21213412", + "23131141", "12231142", "21331141", "13122142", "13131232", + "11322142", "22231231", "11331232", "23113141", "12213142", + "23122231", "12222232", "23131321", "12231322", "21331321", + "13113232", "13122322", "11313232", "13131412", "11322322", + "22231411", "11331412", "23113321", "12213322", "23122411", + "12222412", "21322411", "13113412", "22213411", "11313412", + "13231141", "11431141", "14122141", "14131231", "12322141", + "12331231", "13213141", "13222231", "11413141", "13231321", + /* Column 13 */ + "11422231", "11431321", "14113231", "14122321", "12313231", + "14131411", "12322321", "12331411", "13213321", "13222411", + "11413321", "11422411", "14113411", "12313411", "21141142", + "11132143", "31132141", "11141233", "31141231", "21123142", + "21132232", "21141322", "11114143", "31114141", "11123233", + "31123231", "11132323", "31132321", "11141413", "31141411", + "21114232", "21123322", "21132412", "11114323", "31114321", + "11123413", "31123411", "22141141", "11241142", "12132142", + "12141232", "21241231", "22123141", "11223142", "22132231", + "11232232", "22141321", "11241322", "12114142", "12123232", + "12132322", "12141412", "21241411", "22114231", "11214232", + "22123321", "11223322", "22132411", + /* Column 14 */ + "11232412", "12114322", + "12123412", "21223411", "12241141", "13132141", "13141231", + "11332141", "11341231", "12223141", "12232231", "12241321", + "13114141", "13123231", "11314141", "13132321", "11323231", + "13141411", "11332321", "11341411", "12214231", "12223321", + "12232411", "13114321", "13123411", "11314321", "11323411", + "21151141", "11142142", "11151232", "21133141", "21142231", + "21151321", "11124142", "11133232", "11142322", "11151412", + "21115141", "21124231", "21133321", "21142411", "11115232", + "11124322", "11133412", "11251141", "12142141", "12151231", + "11233141", "11242231", "11251321", "12124141", "12133231", + "12142321", "12151411", "11215141", "11224231", "11233321", + "11242411", + /* Column 15 */ + "12115231", "12124321", "12133411", "11152141", + "11161231", "11134141", "11143231", "11152321", "11161411", + "11116141", "11125231", "11134321", "11143411", "21111244", + "41111242", "11111335", "31111333", "51111331", "21111424", + "41111422", "11111515", "31111513", "51111511", "21211153", + "41211151", "22111243", "42111241", "11211244", "31211242", + "12111334", "32111332", "21211333", "41211331", "22111423", + "42111421", "11211424", "31211422", "12111514", "32111512", + "21211513", "41211511", "22211152", "11311153", "31311151", + "23111242", "12211243", "32211241", "21311242", "13111333", + "33111331", "22211332", "11311333", "31311331", "23111422", + "12211423", "32211421", "21311422", "13111513", + /* Column 16 */ + "33111511", + "22211512", "11311513", "31311511", "23211151", "12311152", + "21411151", "24111241", "13211242", "22311241", "11411242", + "14111332", "23211331", "12311332", "21411331", "24111421", + "13211422", "22311421", "11411422", "14111512", "23211511", + "12311512", "21411511", "13311151", "11511151", "14211241", + "12411241", "15111331", "13311331", "11511331", "14211421", + "12411421", "15111511", "13311511", "11511511", "31121152", + "21112153", "41112151", "21121243", "41121241", "11112244", + "31112242", "11121334", "31121332", "21112333", "41112331", + "21121423", "41121421", "11112424", "31112422", "11121514", + "31121512", "21112513", "41112511", "12121153", "32121151", + "21221152", "22112152", + /* Column 17 */ + "11212153", "22121242", "11221243", + "31221241", "12112243", "32112241", "12121333", "32121331", + "21221332", "22112332", "11212333", "22121422", "11221423", + "31221421", "12112423", "32112421", "12121513", "32121511", + "21221512", "22112512", "11212513", "31212511", "13121152", + "22221151", "11321152", "23112151", "12212152", "23121241", + "12221242", "21321241", "13112242", "13121332", "11312242", + "22221331", "11321332", "23112331", "12212332", "23121421", + "12221422", "21321421", "13112422", "13121512", "11312422", + "22221511", "11321512", "23112511", "12212512", "21312511", + "14121151", "12321151", "13212151", "13221241", "11412151", + "11421241", "14112241", "14121331", "12312241", "12321331", + /* Column 18 */ + "13212331", "13221421", "11412331", "11421421", "14112421", + "14121511", "12312421", "12321511", "13212511", "11412511", + "11131153", "31131151", "21122152", "21131242", "11113153", + "31113151", "11122243", "31122241", "11131333", "31131331", + "21113242", "21122332", "21131422", "11113333", "31113331", + "11122423", "31122421", "11131513", "31131511", "21113422", + "21122512", "12131152", "21231151", "22122151", "11222152", + "22131241", "11231242", "12113152", "12122242", "12131332", + "21231331", "22113241", "11213242", "22122331", "11222332", + "22131421", "11231422", "12113332", "12122422", "12131512", + "21231511", "22113421", "11213422", "22122511", "11222512", + "13131151", "11331151", "12222151", + /* Column 19 */ + "12231241", "13113151", + "13122241", "11313151", "13131331", "11322241", "11331331", + "12213241", "12222331", "12231421", "13113331", "13122421", + "11313331", "13131511", "11322421", "11331511", "12213421", + "12222511", "11141152", "21132151", "21141241", "11123152", + "11132242", "11141332", "21114151", "21123241", "21132331", + "21141421", "11114242", "11123332", "11132422", "11141512", + "21114331", "21123421", "21132511", "12141151", "11232151", + "11241241", "12123151", "12132241", "12141331", "11214151", + "11223241", "11232331", "11241421", "12114241", "12123331", + "12132421", "12141511", "11214331", "11223421", "11232511", + "11151151", "11133151", "11142241", "11151331", "11115151", + "11124241", + /* Column 20 */ + "11133331", "11142421", "11151511", "11111254", + "31111252", "21111343", "41111341", "11111434", "31111432", + "21111523", "41111521", "11111614", "31111612", "31211161", + "12111253", "32111251", "21211252", "22111342", "11211343", + "31211341", "12111433", "32111431", "21211432", "22111522", + "11211523", "31211521", "12111613", "32111611", "21211612", + "12211162", "21311161", "13111252", "22211251", "11311252", + "23111341", "12211342", "21311341", "13111432", "22211431", + "11311432", "23111521", "12211522", "21311521", "13111612", + "22211611", "11311612", "13211161", "11411161", "14111251", + "12311251", "13211341", "11411341", "14111431", "12311431", + "13211521", "11411521", "14111611", "12311611", + /* Column 21 */ + "21121162", + "11112163", "31112161", "11121253", "31121251", "21112252", + "21121342", "11112343", "31112341", "11121433", "31121431", + "21112432", "21121522", "11112523", "31112521", "11121613", + "31121611", "22121161", "11221162", "12112162", "12121252", + "21221251", "22112251", "11212252", "22121341", "11221342", + "12112342", "12121432", "21221431", "22112431", "11212432", + "22121521", "11221522", "12112522", "12121612", "21221611", + "12221161", "13112161", "13121251", "11312161", "11321251", + "32121115", "52121113", "21221116", "41221114", "61221112", + "22112116", "42112114", "31212115", "51212113", "13121116", + "33121114", "22221115", "42221113", "11321116", "31321114", + "51321112", "23112115", + /* Column 22 */ + "43112113", "12212116", "32212114", + "52212112", "21312115", "41312113", "61312111", "14121115", + "34121113", "23221114", "43221112", "12321115", "32321113", + "52321111", "21421114", "41421112", "24112114", "13212115", + "33212113", "22312114", "42312112", "11412115", "31412113", + "51412111", "15121114", "24221113", "13321114", "33321112", + "22421113", "42421111", "11521114", "31521112", "25112113", + "14212114", "34212112", "23312113", "43312111", "12412114", + "32412112", "21512113", "41512111", "16121113", "25221112", + "14321113", "34321111", "23421112", "12521113", "32521111", + "15212113", "24312112", "13412113", "33412111", "22512112", + "11612113", "31612111", "31131115", "51131113", "21122116", + /* Column 23 */ + "41122114", "61122112", "31113115", "51113113", "12131116", + "32131114", "52131112", "21231115", "41231113", "61231111", + "22122115", "42122113", "11222116", "31222114", "51222112", + "12113116", "32113114", "52113112", "21213115", "41213113", + "61213111", "13131115", "33131113", "22231114", "42231112", + "11331115", "31331113", "51331111", "23122114", "43122112", + "12222115", "32222113", "52222111", "21322114", "41322112", + "13113115", "33113113", "22213114", "42213112", "11313115", + "31313113", "51313111", "14131114", "34131112", "23231113", + "43231111", "12331114", "32331112", "21431113", "41431111", + "24122113", "13222114", "33222112", "22322113", "42322111", + "11422114", "31422112", "14113114", + /* Column 24 */ + "34113112", "23213113", + "43213111", "12313114", "32313112", "21413113", "41413111", + "15131113", "24231112", "13331113", "33331111", "22431112", + "25122112", "14222113", "34222111", "23322112", "12422113", + "32422111", "21522112", "15113113", "24213112", "13313113", + "33313111", "22413112", "11513113", "31513111", "16131112", + "25231111", "14331112", "23431111", "15222112", "24322111", + "13422112", "22522111", "16113112", "25213111", "14313112", + "23413111", "12513112", "21613111", "11141116", "31141114", + "51141112", "21132115", "41132113", "61132111", "11123116", + "31123114", "51123112", "21114115", "41114113", "61114111", + "12141115", "32141113", "52141111", "21241114", "41241112", + "22132114", + /* Column 25 */ + "42132112", "11232115", "31232113", "51232111", + "12123115", "32123113", "52123111", "21223114", "41223112", + "22114114", "42114112", "11214115", "31214113", "51214111", + "13141114", "33141112", "22241113", "42241111", "11341114", + "31341112", "23132113", "43132111", "12232114", "32232112", + "21332113", "41332111", "13123114", "33123112", "22223113", + "42223111", "11323114", "31323112", "23114113", "43114111", + "12214114", "32214112", "21314113", "41314111", "14141113", + "34141111", "23241112", "12341113", "32341111", "24132112", + "13232113", "33232111", "22332112", "11432113", "31432111", + "14123113", "34123111", "23223112", "12323113", "32323111", + "21423112", "24114112", "13214113", "33214111", + /* Column 26 */ + "22314112", + "11414113", "31414111", "15141112", "24241111", "13341112", + "25132111", "14232112", "23332111", "12432112", "15123112", + "24223111", "13323112", "22423111", "11523112", "25114111", + "14214112", "23314111", "12414112", "21514111", "16141111", + "14341111", "15232111", "13432111", "16123111", "14323111", + "12523111", "15214111", "13414111", "11614111", "11151115", + "31151113", "51151111", "21142114", "41142112", "11133115", + "31133113", "51133111", "21124114", "41124112", "11115115", + "31115113", "51115111", "12151114", "32151112", "21251113", + "41251111", "22142113", "42142111", "11242114", "31242112", + "12133114", "32133112", "21233113", "41233111", "22124113", + "42124111", "11224114", + /* Column 27 */ + "31224112", "12115114", "32115112", + "21215113", "41215111", "13151113", "33151111", "22251112", + "23142112", "12242113", "32242111", "21342112", "13133113", + "33133111", "22233112", "11333113", "31333111", "23124112", + "12224113", "32224111", "21324112", "13115113", "33115111", + "22215112", "11315113", "31315111", "14151112", "23251111", + "24142111", "13242112", "22342111", "14133112", "23233111", + "12333112", "21433111", "24124111", "13224112", "22324111", + "11424112", "14115112", "23215111", "12315112", "21415111", + "15151111", "14242111", "15133111", "13333111", "14224111", + "12424111", "15115111", "13315111", "11515111", "11161114", + "31161112", "21152113", "41152111", "11143114", "31143112", + /* Column 28 */ + "21134113", "41134111", "11125114", "31125112", "21116113", + "41116111", "12161113", "32161111", "22152112", "11252113", + "31252111", "12143113", "32143111", "21243112", "22134112", + "11234113", "31234111", "12125113", "32125111", "21225112", + "22116112", "11216113", "31216111", "13161112", "23152111", + "12252112", "13143112", "22243111", "11343112", "23134111", + "12234112", "21334111", "13125112", "22225111", "11325112", + "23116111", "12216112", "21316111", "14161111", "13252111", + "14143111", "12343111", "13234111", "11434111", "14125111", + "12325111", "13216111", "11416111", "31111216", "51111214", + "31211125", "51211123", "32111215", "52111213", "21211216", + "41211214", "61211212", "12211126", + /* Column 29 */ + "32211124", "52211122", + "21311125", "41311123", "61311121", "13111216", "33111214", + "22211215", "42211213", "11311216", "31311214", "51311212", + "13211125", "33211123", "22311124", "42311122", "11411125", + "31411123", "51411121", "14111215", "34111213", "23211214", + "43211212", "12311215", "32311213", "52311211", "21411214", + "41411212", "14211124", "34211122", "23311123", "43311121", + "12411124", "32411122", "21511123", "41511121", "15111214", + "24211213", "13311214", "33311212", "22411213", "42411211", + "11511214", "31511212", "15211123", "24311122", "13411123", + "33411121", "22511122", "11611123", "31611121", "16111213", + "25211212", "14311213", "34311211", "23411212", "12511213", + "32511211", + /* Column 30 */ + "21611212", "21121126", "41121124", "61121122", + "31112125", "51112123", "31121215", "51121213", "21112216", + "41112214", "61112212", "22121125", "42121123", "11221126", + "31221124", "51221122", "12112126", "32112124", "52112122", + "12121216", "32121214", "52121212", "21221215", "41221213", + "61221211", "22112215", "42112213", "11212216", "31212214", + "51212212", "23121124", "43121122", "12221125", "32221123", + "52221121", "21321124", "41321122", "13112125", "33112123", + "13121215", "33121213", "11312125", "22221214", "42221212", + "11321215", "31321213", "51321211", "23112214", "43112212", + "12212215", "32212213", "52212211", "21312214", "41312212", + "24121123", "13221124", "33221122", "22321123", + /* Column 31 */ + "42321121", + "11421124", "31421122", "14112124", "34112122", "14121214", + "34121212", "12312124", "23221213", "43221211", "12321214", + "32321212", "21421213", "41421211", "24112213", "13212214", + "33212212", "22312213", "42312211", "11412214", "31412212", + "25121122", "14221123", "34221121", "23321122", "12421123", + "32421121", "21521122", "15112123", "15121213", "13312123", + "24221212", "13321213", "33321211", "11512123", "22421212", + "11521213", "31521211", "25112212", "14212213", "34212211", + "23312212", "12412213", "32412211", "21512212", "15221122", + "24321121", "13421122", "22521121", "16112122", "16121212", + "14312122", "25221211", "14321212", "12512122", "23421211", + "12521212", "15212212", + /* Column 32 */ + "24312211", "13412212", "22512211", + "11612212", "21131125", "41131123", "61131121", "11122126", + "31122124", "51122122", "11131216", "31131214", "51131212", + "21113125", "41113123", "61113121", "21122215", "41122213", + "61122211", "11113216", "31113214", "51113212", "22131124", + "42131122", "11231125", "31231123", "51231121", "12122125", + "32122123", "52122121", "12131215", "32131213", "52131211", + "21231214", "41231212", "22113124", "42113122", "11213125", + "22122214", "42122212", "11222215", "31222213", "51222211", + "12113215", "32113213", "52113211", "21213214", "41213212", + "23131123", "43131121", "12231124", "32231122", "21331123", + "41331121", "13122124", "33122122", "13131214", "33131212", + /* Column 33 */ + "11322124", "22231213", "42231211", "11331214", "31331212", + "23113123", "43113121", "12213124", "23122213", "43122211", + "12222214", "32222212", "21322213", "41322211", "13113214", + "33113212", "22213213", "42213211", "11313214", "31313212", + "24131122", "13231123", "33231121", "22331122", "11431123", + "31431121", "14122123", "34122121", "14131213", "34131211", + "12322123", "23231212", "12331213", "32331211", "21431212", + "24113122", "13213123", "24122212", "13222213", "33222211", + "11413123", "22322212", "11422213", "31422211", "14113213", + "34113211", "23213212", "12313213", "32313211", "21413212", + "25131121", "14231122", "23331121", "12431122", "15122122", + "15131212", "13322122", "24231211", + /* Column 34 */ + "13331212", "11522122", + "22431211", "25113121", "14213122", "25122211", "14222212", + "12413122", "23322211", "12422212", "21522211", "15113212", + "24213211", "13313212", "22413211", "11513212", "15231121", + "13431121", "16122121", "16131211", "14322121", "14331211", + "12522121", "15213121", "15222211", "13413121", "13422211", + "11613121", "16113211", "14313211", "12513211", "21141124", + "41141122", "11132125", "31132123", "51132121", "11141215", + "31141213", "51141211", "21123124", "41123122", "21132214", + "41132212", "11114125", "31114123", "51114121", "11123215", + "31123213", "51123211", "21114214", "41114212", "22141123", + "42141121", "11241124", "31241122", "12132124", "32132122", + "12141214", + /* Column 35 */ + "32141212", "21241213", "41241211", "22123123", + "42123121", "11223124", "22132213", "42132211", "11232214", + "31232212", "12114124", "32114122", "12123214", "32123212", + "21223213", "41223211", "22114213", "42114211", "11214214", + "31214212", "23141122", "12241123", "32241121", "21341122", + "13132123", "33132121", "13141213", "33141211", "11332123", + "22241212", "11341213", "31341211", "23123122", "12223123", + "23132212", "12232213", "32232211", "21332212", "13114123", + "33114121", "13123213", "33123211", "11314123", "22223212", + "11323213", "31323211", "23114212", "12214213", "32214211", + "21314212", "24141121", "13241122", "22341121", "14132122", + "14141212", "12332122", "23241211", "12341212", + /* Column 36 */ + "24123121", + "13223122", "24132211", "13232212", "11423122", "22332211", + "11432212", "14114122", "14123212", "12314122", "23223211", + "12323212", "21423211", "24114211", "13214212", "22314211", + "11414212", "14241121", "15132121", "15141211", "13332121", + "13341211", "14223121", "14232211", "12423121", "12432211", + "15114121", "15123211", "13314121", "13323211", "11514121", + "11523211", "14214211", "12414211", "21151123", "41151121", + "11142124", "31142122", "11151214", "31151212", "21133123", + "41133121", "21142213", "41142211", "11124124", "31124122", + "11133214", "31133212", "21115123", "41115121", "21124213", + "41124211", "11115214", "31115212", "22151122", "11251123", + "31251121", "12142123", + /* Column 37 */ + "32142121", "12151213", "32151211", + "21251212", "22133122", "11233123", "22142212", "11242213", + "31242211", "12124123", "32124121", "12133213", "32133211", + "21233212", "22115122", "11215123", "22124212", "11224213", + "31224211", "12115213", "32115211", "21215212", "23151121", + "12251122", "13142122", "13151212", "11342122", "22251211", + "23133121", "12233122", "23142211", "12242212", "21342211", + "13124122", "13133212", "11324122", "22233211", "11333212", + "23115121", "12215122", "23124211", "12224212", "21324211", + "13115212", "22215211", "11315212", "13251121", "14142121", + "14151211", "12342121", "13233121", "13242211", "11433121", + "14124121", "14133211", "12324121", "12333211", "13215121", + /* Column 38 */ + "13224211", "11415121", "11424211", "14115211", "12315211", + "21161122", "11152123", "31152121", "11161213", "31161211", + "21143122", "21152212", "11134123", "31134121", "11143213", + "31143211", "21125122", "21134212", "11116123", "31116121", + "11125213", "31125211", "22161121", "12152122", "12161212", + "22143121", "11243122", "22152211", "11252212", "12134122", + "12143212", "21243211", "22125121", "11225122", "22134211", + "11234212", "12116122", "12125212", "21225211", "13152121", + "13161211", "12243121", "12252211", "13134121", "13143211", + "11334121", "11343211", "12225121", "12234211", "13116121", + "13125211", "11316121", "11325211", "21111226", "41111224", + "61111222", "31111315", "51111313", + /* Column 39 */ + "21211135", "41211133", + "61211131", "22111225", "42111223", "11211226", "31211224", + "51211222", "12111316", "32111314", "52111312", "21211315", + "41211313", "61211311", "22211134", "42211132", "11311135", + "31311133", "51311131", "23111224", "43111222", "12211225", + "32211223", "52211221", "21311224", "41311222", "13111315", + "33111313", "22211314", "42211312", "11311315", "31311313", + "51311311", "23211133", "43211131", "12311134", "32311132", + "21411133", "41411131", "24111223", "13211224", "33211222", + "22311223", "42311221", "11411224", "31411222", "14111314", + "34111312", "23211313", "43211311", "12311314", "32311312", + "21411313", "41411311", "24211132", "13311133", "33311131", + "22411132", + /* Column 40 */ + "11511133", "31511131", "25111222", "14211223", + "34211221", "23311222", "12411223", "32411221", "21511222", + "15111313", "24211312", "13311313", "33311311", "22411312", + "11511313", "31511311", "25211131", "14311132", "23411131", + "12511132", "21611131", "15211222", "24311221", "13411222", + "22511221", "11611222", "16111312", "25211311", "14311312", + "23411311", "12511312", "21611311", "31121134", "51121132", + "21112135", "41112133", "61112131", "21121225", "41121223", + "61121221", "11112226", "31112224", "51112222", "11121316", + "31121314", "51121312", "21112315", "41112313", "61112311", + "12121135", "32121133", "52121131", "21221134", "41221132", + "22112134", "42112132", "11212135", "22121224", + /* Column 41 */ + "42121222", + "11221225", "31221223", "51221221", "12112225", "32112223", + "52112221", "12121315", "32121313", "52121311", "21221314", + "41221312", "22112314", "42112312", "11212315", "31212313", + "51212311", "13121134", "33121132", "22221133", "42221131", + "11321134", "31321132", "23112133", "43112131", "12212134", + "23121223", "43121221", "12221224", "32221222", "21321223", + "41321221", "13112224", "33112222", "13121314", "33121312", + "11312224", "22221313", "42221311", "11321314", "31321312", + /* Column 42 */ + "23112313", "43112311", "12212314", "32212312", "21312313", + "41312311", "14121133", "34121131", "23221132", "12321133", + "32321131", "21421132", "24112132", "13212133", "24121222", + "13221223", "33221221", "11412133", "22321222", "11421223", + "31421221", "14112223", "34112221", "14121313", "34121311", + "12312223", "23221312", "12321313", "32321311", "21421312", + "24112312", "13212313", "33212311", "22312312", "11412313", + "31412311", "15121132", "24221131", "13321132", "22421131" +}; + +static char *c49_appxe_odd[2401] = { + /* Appendix E - Code 49 Encodation Patterns (Odd Symbol Character Parity) */ + /* Column 1 */ + "22121116", + "42121114", "31221115", "51221113", "32112115", "52112113", + "21212116", "41212114", "61212112", "23121115", "43121113", + "12221116", "32221114", "52221112", "21321115", "41321113", + "61321111", "13112116", "33112114", "22212115", "42212113", + "11312116", "31312114", "51312112", "24121114", "13221115", + "33221113", "22321114", "42321112", "11421115", "31421113", + "51421111", "14112115", "34112113", "23212114", "43212112", + "12312115", "32312113", "52312111", "21412114", "41412112", + "25121113", "14221114", "34221112", "23321113", "43321111", + "12421114", "32421112", "21521113", "41521111", "15112114", + "24212113", "13312114", "33312112", "22412113", "42412111", + "11512114", "31512112", + /* Column 2 */ + "15221113", "24321112", "13421113", + "33421111", "22521112", "16112113", "25212112", "14312113", + "34312111", "23412112", "12512113", "32512111", "21612112", + "21131116", "41131114", "61131112", "31122115", "51122113", + "21113116", "41113114", "61113112", "22131115", "42131113", + "11231116", "31231114", "51231112", "12122116", "32122114", + "52122112", "21222115", "41222113", "61222111", "22113115", + "42113113", "11213116", "31213114", "51213112", "23131114", + "43131112", "12231115", "32231113", "52231111", "21331114", + "41331112", "13122115", "33122113", "22222114", "42222112", + "11322115", "31322113", "51322111", "23113114", "43113112", + "12213115", "32213113", "52213111", "21313114", "41313112", + /* Column 3 */ + "24131113", "13231114", "33231112", "22331113", "42331111", + "11431114", "31431112", "14122114", "34122112", "23222113", + "43222111", "12322114", "32322112", "21422113", "41422111", + "24113113", "13213114", "33213112", "22313113", "42313111", + "11413114", "31413112", "25131112", "14231113", "34231111", + "23331112", "12431113", "32431111", "15122113", "24222112", + "13322113", "33322111", "22422112", "11522113", "31522111", + "25113112", "14213113", "34213111", "23313112", "12413113", + "32413111", "21513112", "15231112", "24331111", "13431112", + "16122112", "25222111", "14322112", "23422111", "12522112", + "15213112", "24313111", "13413112", "22513111", "11613112", + "21141115", "41141113", "61141111", + /* Column 4 */ + "11132116", "31132114", + "51132112", "21123115", "41123113", "61123111", "11114116", + "31114114", "51114112", "22141114", "42141112", "11241115", + "31241113", "51241111", "12132115", "32132113", "52132111", + "21232114", "41232112", "22123114", "42123112", "11223115", + "31223113", "51223111", "12114115", "32114113", "52114111", + "21214114", "41214112", "23141113", "43141111", "12241114", + "32241112", "21341113", "41341111", "13132114", "33132112", + "22232113", "42232111", "11332114", "31332112", "23123113", + "43123111", "12223114", "32223112", "21323113", "41323111", + "13114114", "33114112", "22214113", "42214111", "11314114", + "31314112", "24141112", "13241113", "33241111", "22341112", + "14132113", + /* Column 5 */ + "34132111", "23232112", "12332113", "32332111", + "21432112", "24123112", "13223113", "33223111", "22323112", + "11423113", "31423111", "14114113", "34114111", "23214112", + "12314113", "32314111", "21414112", "25141111", "14241112", + "23341111", "15132112", "24232111", "13332112", "22432111", + "25123111", "14223112", "23323111", "12423112", "21523111", + "15114112", "24214111", "13314112", "22414111", "11514112", + "15241111", "16132111", "14332111", "15223111", "13423111", + "16114111", "14314111", "12514111", "21151114", "41151112", + "11142115", "31142113", "51142111", "21133114", "41133112", + "11124115", "31124113", "51124111", "21115114", "41115112", + "22151113", "42151111", "11251114", "31251112", + /* Column 6 */ + "12142114", + "32142112", "21242113", "41242111", "22133113", "42133111", + "11233114", "31233112", "12124114", "32124112", "21224113", + "41224111", "22115113", "42115111", "11215114", "31215112", + "23151112", "12251113", "32251111", "13142113", "33142111", + "22242112", "11342113", "31342111", "23133112", "12233113", + "32233111", "21333112", "13124113", "33124111", "22224112", + "11324113", "31324111", "23115112", "12215113", "32215111", + "21315112", "24151111", "13251112", "14142112", "23242111", + "12342112", "24133111", "13233112", "22333111", "11433112", + "14124112", "23224111", "12324112", "21424111", "24115111", + "13215112", "22315111", "11415112", "14251111", "15142111", + "13342111", "14233111", + /* Column 7 */ + "12433111", "15124111", "13324111", + "11524111", "14215111", "12415111", "21161113", "41161111", + "11152114", "31152112", "21143113", "41143111", "11134114", + "31134112", "21125113", "41125111", "11116114", "31116112", + "22161112", "12152113", "32152111", "21252112", "22143112", + "11243113", "31243111", "12134113", "32134111", "21234112", + "22125112", "11225113", "31225111", "12116113", "32116111", + "21216112", "23161111", "13152112", "22252111", "23143111", + "12243112", "21343111", "13134112", "22234111", "11334112", + "23125111", "12225112", "21325111", "13116112", "22216111", + "11316112", "14152111", "13243111", "14134111", "12334111", + "13225111", "11425111", "14116111", "12316111", "41111215", + /* Column 8 */ + "61111213", "21211126", "41211124", "61211122", "22111216", + "42111214", "31211215", "51211213", "22211125", "42211123", + "11311126", "31311124", "51311122", "23111215", "43111213", + "12211216", "32211214", "52211212", "21311215", "41311213", + "61311211", "23211124", "43211122", "12311125", "32311123", + "52311121", "21411124", "41411122", "24111214", "13211215", + "33211213", "22311214", "42311212", "11411215", "31411213", + "51411211", "24211123", "13311124", "33311122", "22411123", + "42411121", "11511124", "31511122", "25111213", "14211214", + "34211212", "23311213", "43311211", "12411214", "32411212", + "21511213", "41511211", "25211122", "14311123", "34311121", + "23411122", "12511123", "32511121", + /* Column 9 */ + "21611122", "15211213", + "24311212", "13411213", "33411211", "22511212", "11611213", + "31611211", "31121125", "51121123", "21112126", "41112124", + "61112122", "21121216", "41121214", "61121212", "31112215", + "51112213", "12121126", "32121124", "52121122", "21221125", + "41221123", "61221121", "22112125", "42112123", "11212126", + "22121215", "42121213", "11221216", "31221214", "51221212", + "12112216", "32112214", "52112212", "21212215", "41212213", + "61212211", "13121125", "33121123", "22221124", "42221122", + "11321125", "31321123", "51321121", "23112124", "43112122", + "12212125", "23121214", "43121212", "12221215", "32221213", + "52221211", "21321214", "41321212", "13112215", "33112213", + "22212214", + /* Column 10 */ + "42212212", "11312215", "31312213", "51312211", + "14121124", "34121122", "23221123", "43221121", "12321124", + "32321122", "21421123", "41421121", "24112123", "13212124", + "24121213", "13221214", "33221212", "11412124", "22321213", + "42321211", "11421214", "31421212", "14112214", "34112212", + "23212213", "43212211", "12312214", "32312212", "21412213", + "41412211", "15121123", "24221122", "13321123", "33321121", + "22421122", "11521123", "31521121", "25112122", "14212123", + "25121212", "14221213", "34221211", "12412123", "23321212", + "12421213", "32421211", "21521212", "15112213", "24212212", + "13312213", "33312211", "22412212", "11512213", "31512211", + "16121122", "25221121", "14321122", "23421121", + /* Column 11 */ + "12521122", + "15212122", "15221212", "13412122", "24321211", "13421212", + "11612122", "22521211", "16112212", "25212211", "14312212", + "23412211", "12512212", "21612211", "11131126", "31131124", + "51131122", "21122125", "41122123", "61122121", "21131215", + "41131213", "61131211", "11113126", "31113124", "51113122", + "11122216", "31122214", "51122212", "21113215", "41113213", + "61113211", "12131125", "32131123", "52131121", "21231124", + "41231122", "22122124", "42122122", "11222125", "22131214", + "42131212", "11231215", "31231213", "51231211", "12113125", + "32113123", "52113121", "12122215", "32122213", "52122211", + "21222214", "41222212", "22113214", "42113212", "11213215", + "31213213", "51213211", + /* Column 12 */ + "13131124", "33131122", "22231123", + "42231121", "11331124", "31331122", "23122123", "43122121", + "12222124", "23131213", "43131211", "12231214", "32231212", + "21331213", "41331211", "13113124", "33113122", "13122214", + "33122212", "11313124", "22222213", "42222211", "11322214", + "31322212", "23113213", "43113211", "12213214", "32213212", + "21313213", "41313211", "14131123", "34131121", "23231122", + "12331123", "32331121", "21431122", "24122122", "13222123", + "24131212", "13231213", "33231211", "11422123", "22331212", + "11431213", "31431211", "14113123", "34113121", "14122213", + "34122211", "12313123", "23222212", "12322213", "32322211", + "21422212", "24113212", "13213213", "33213211", "22313212", + /* Column 13 */ + "11413213", "31413211", "15131122", "24231121", "13331122", + "22431121", "25122121", "14222122", "25131211", "14231212", + "12422122", "23331211", "12431212", "15113122", "15122212", + "13313122", "24222211", "13322212", "11513122", "22422211", + "11522212", "25113211", "14213212", "23313211", "12413212", + "21513211", "16131121", "14331121", "15222121", "15231211", + "13422121", "13431211", "16113121", "16122211", "14313121", + "14322211", "12513121", "12522211", "15213211", "13413211", + "11613211", "11141125", "31141123", "51141121", "21132124", + "41132122", "21141214", "41141212", "11123125", "31123123", + "51123121", "11132215", "31132213", "51132211", "21114124", + "41114122", "21123214", "41123212", + /* Column 14 */ + "11114215", "31114213", + "51114211", "12141124", "32141122", "21241123", "41241121", + "22132123", "42132121", "11232124", "22141213", "42141211", + "11241214", "31241212", "12123124", "32123122", "12132214", + "32132212", "21232213", "41232211", "22114123", "42114121", + "11214124", "22123213", "42123211", "11223214", "31223212", + "12114214", "32114212", "21214213", "41214211", "13141123", + "33141121", "22241122", "11341123", "31341121", "23132122", + "12232123", "23141212", "12241213", "32241211", "21341212", + "13123123", "33123121", "13132213", "33132211", "11323123", + "22232212", "11332213", "31332211", "23114122", "12214123", + "23123212", "12223213", "32223211", "21323212", "13114213", + "33114211", + /* Column 15 */ + "22214212", "11314213", "31314211", "14141122", + "23241121", "12341122", "24132121", "13232122", "24141211", + "13241212", "11432122", "22341211", "14123122", "14132212", + "12323122", "23232211", "12332212", "21432211", "24114121", + "13214122", "24123211", "13223212", "11414122", "22323211", + "11423212", "14114212", "23214211", "12314212", "21414211", + "15141121", "13341121", "14232121", "14241211", "12432121", + "15123121", "15132211", "13323121", "13332211", "11523121", + "14214121", "14223211", "12414121", "12423211", "15114211", + "13314211", "11514211", "11151124", "31151122", "21142123", + "41142121", "21151213", "41151211", "11133124", "31133122", + "11142214", "31142212", "21124123", "41124121", + /* Column 16 */ + "21133213", + "41133211", "11115124", "31115122", "11124214", "31124212", + "21115213", "41115211", "12151123", "32151121", "21251122", + "22142122", "11242123", "22151212", "11251213", "31251211", + "12133123", "32133121", "12142213", "32142211", "21242212", + "22124122", "11224123", "22133212", "11233213", "31233211", + "12115123", "32115121", "12124213", "32124211", "21224212", + "22115212", "11215213", "31215211", "13151122", "22251121", + "23142121", "12242122", "23151211", "12251212", "13133122", + "13142212", "11333122", "22242211", "11342212", "23124121", + "12224122", "23133211", "12233212", "21333211", "13115122", + "13124212", "11315122", "22224211", "11324212", "23115211", + "12215212", "21315211", + /* Column 17 */ + "14151121", "13242121", "13251211", + "14133121", "14142211", "12333121", "12342211", "13224121", + "13233211", "11424121", "11433211", "14115121", "14124211", + "12315121", "12324211", "13215211", "11415211", "11161123", + "31161121", "21152122", "21161212", "11143123", "31143121", + "11152213", "31152211", "21134122", "21143212", "11125123", + "31125121", "11134213", "31134211", "21116122", "21125212", + "12161122", "22152121", "11252122", "22161211", "12143122", + "12152212", "21252211", "22134121", "11234122", "22143211", + "11243212", "12125122", "12134212", "21234211", "22116121", + "11216122", "22125211", "11225212", "13161121", "12252121", + "13143121", "13152211", "11343121", "12234121", "12243211", + /* Column 18 */ + "13125121", "13134211", "11325121", "11334211", "12216121", + "12225211", "31111225", "51111223", "21111316", "41111314", + "61111312", "31211134", "51211132", "12111226", "32111224", + "52111222", "21211225", "41211223", "61211221", "22111315", + "42111313", "11211316", "31211314", "51211312", "12211135", + "32211133", "52211131", "21311134", "41311132", "13111225", + "33111223", "22211224", "42211222", "11311225", "31311223", + "51311221", "23111314", "43111312", "12211315", "32211313", + "52211311", "21311314", "41311312", "13211134", "33211132", + "22311133", "42311131", "11411134", "31411132", "14111224", + "34111222", "23211223", "43211221", "12311224", "32311222", + "21411223", "41411221", "24111313", + /* Column 19 */ + "13211314", "33211312", + "22311313", "42311311", "11411314", "31411312", "14211133", + "34211131", "23311132", "12411133", "32411131", "21511132", + "15111223", "24211222", "13311223", "33311221", "22411222", + "11511223", "31511221", "25111312", "14211313", "34211311", + "23311312", "12411313", "32411311", "21511312", "15211132", + "24311131", "13411132", "22511131", "11611132", "16111222", + "25211221", "14311222", "23411221", "12511222", "21611221", + "15211312", "24311311", "13411312", "22511311", "11611312", + "21121135", "41121133", "61121131", "11112136", "31112134", + "51112132", "11121226", "31121224", "51121222", "21112225", + "41112223", "61112221", "21121315", "41121313", "61121311", + "11112316", + /* Column 20 */ + "31112314", "51112312", "22121134", "42121132", + "11221135", "31221133", "51221131", "12112135", "32112133", + "52112131", "12121225", "32121223", "52121221", "21221224", + "41221222", "22112224", "42112222", "11212225", "22121314", + "42121312", "11221315", "31221313", "51221311", "12112315", + "32112313", "52112311", "21212314", "41212312", "23121133", + "43121131", "12221134", "32221132", "21321133", "41321131", + "13112134", "33112132", "13121224", "33121222", "11312134", + "22221223", "42221221", "11321224", "31321222", "23112223", + "43112221", "12212224", "23121313", "43121311", "12221314", + "32221312", "21321313", "41321311", "13112314", "33112312", + "22212313", "42212311", "11312314", "31312312", + /* Column 21 */ + "24121132", + "13221133", "33221131", "22321132", "11421133", "31421131", + "14112133", "34112131", "14121223", "34121221", "12312133", + "23221222", "12321223", "32321221", "21421222", "24112222", + "13212223", "24121312", "13221313", "33221311", "11412223", + "22321312", "11421313", "31421311", "14112313", "34112311", + "23212312", "12312313", "32312311", "21412312", "25121131", + "14221132", "23321131", "12421132", "21521131", "15112132", + "15121222", "13312132", "24221221", "13321222", "11512132", + "22421221", "11521222", "25112221", "14212222", "25121311", + "14221312", "12412222", "23321311", "12421312", "21521311", + "15112312", "24212311", "13312312", "22412311", "11512312", + "15221131", "13421131", + /* Column 22 */ + "16112131", "16121221", "14312131", + "14321221", "12512131", "12521221", "15212221", "15221311", + "13412221", "13421311", "11612221", "16112311", "14312311", + "12512311", "21131134", "41131132", "11122135", "31122133", + "51122131", "11131225", "31131223", "51131221", "21113134", + "41113132", "21122224", "41122222", "21131314", "41131312", + "11113225", "31113223", "51113221", "11122315", "31122313", + "51122311", "21113314", "41113312", "22131133", "42131131", + "11231134", "31231132", "12122134", "32122132", "12131224", + "32131222", "21231223", "41231221", "22113133", "42113131", + "11213134", "22122223", "42122221", "11222224", "22131313", + "42131311", "11231314", "31231312", "12113224", "32113222", + /* Column 23 */ + "12122314", "32122312", "21222313", "41222311", "22113313", + "42113311", "11213314", "31213312", "23131132", "12231133", + "32231131", "21331132", "13122133", "33122131", "13131223", + "33131221", "11322133", "22231222", "11331223", "31331221", + "23113132", "12213133", "23122222", "12222223", "23131312", + "12231313", "32231311", "21331312", "13113223", "33113221", + "13122313", "33122311", "11313223", "22222312", "11322313", + "31322311", "23113312", "12213313", "32213311", "21313312", + "24131131", "13231132", "22331131", "11431132", "14122132", + "14131222", "12322132", "23231221", "12331222", "21431221", + "24113131", "13213132", "24122221", "13222222", "24131311", + "11413132", "13231312", "11422222", + /* Column 24 */ + "22331311", "11431312", + "14113222", "14122312", "12313222", "23222311", "12322312", + "21422311", "24113311", "13213312", "22313311", "11413312", + "14231131", "12431131", "15122131", "15131221", "13322131", + "13331221", "11522131", "14213131", "14222221", "12413131", + "14231311", "12422221", "12431311", "15113221", "15122311", + "13313221", "13322311", "11513221", "11522311", "14213311", + "12413311", "21141133", "41141131", "11132134", "31132132", + "11141224", "31141222", "21123133", "41123131", "21132223", + "41132221", "21141313", "41141311", "11114134", "31114132", + "11123224", "31123222", "11132314", "31132312", "21114223", + "41114221", "21123313", "41123311", "11114314", "31114312", + "22141132", + /* Column 25 */ + "11241133", "31241131", "12132133", "32132131", + "12141223", "32141221", "21241222", "22123132", "11223133", + "22132222", "11232223", "22141312", "11241313", "31241311", + "12114133", "32114131", "12123223", "32123221", "12132313", + "32132311", "21232312", "22114222", "11214223", "22123312", + "11223313", "31223311", "12114313", "32114311", "21214312", + "23141131", "12241132", "21341131", "13132132", "13141222", + "11332132", "22241221", "11341222", "23123131", "12223132", + "23132221", "12232222", "23141311", "12241312", "21341311", + "13114132", "13123222", "11314132", "13132312", "11323222", + "22232311", "11332312", "23114221", "12214222", "23123311", + "12223312", "21323311", "13114312", "22214311", + /* Column 26 */ + "11314312", + "13241131", "14132131", "14141221", "12332131", "12341221", + "13223131", "13232221", "11423131", "13241311", "11432221", + "14114131", "14123221", "12314131", "14132311", "12323221", + "12332311", "13214221", "13223311", "11414221", "11423311", + "14114311", "12314311", "21151132", "11142133", "31142131", + "11151223", "31151221", "21133132", "21142222", "21151312", + "11124133", "31124131", "11133223", "31133221", "11142313", + "31142311", "21115132", "21124222", "21133312", "11115223", + "31115221", "11124313", "31124311", "22151131", "11251132", + "12142132", "12151222", "21251221", "22133131", "11233132", + "22142221", "11242222", "22151311", "11251312", "12124132", + "12133222", "12142312", + /* Column 27 */ + "21242311", "22115131", "11215132", + "22124221", "11224222", "22133311", "11233312", "12115222", + "12124312", "21224311", "12251131", "13142131", "13151221", + "11342131", "12233131", "12242221", "12251311", "13124131", + "13133221", "11324131", "13142311", "11333221", "11342311", + "12215131", "12224221", "12233311", "13115221", "13124311", + "11315221", "11324311", "21161131", "11152132", "11161222", + "21143131", "21152221", "21161311", "11134132", "11143222", + "11152312", "21125131", "21134221", "21143311", "11116132", + "11125222", "11134312", "12152131", "12161221", "11243131", + "11252221", "12134131", "12143221", "12152311", "11225131", + "11234221", "11243311", "12116131", "12125221", "12134311", + /* Column 28 */ + "21111235", "41111233", "61111231", "11111326", "31111324", + "51111322", "21111415", "41111413", "61111411", "21211144", + "41211142", "22111234", "42111232", "11211235", "31211233", + "51211231", "12111325", "32111323", "52111321", "21211324", + "41211322", "22111414", "42111412", "11211415", "31211413", + "51211411", "22211143", "42211141", "11311144", "31311142", + "23111233", "43111231", "12211234", "32211232", "21311233", + "41311231", "13111324", "33111322", "22211323", "42211321", + "11311324", "31311322", "23111413", "43111411", "12211414", + "32211412", "21311413", "41311411", "23211142", "12311143", + "32311141", "21411142", "24111232", "13211233", "33211231", + "22311232", "11411233", "31411231", + /* Column 29 */ + "14111323", "34111321", + "23211322", "12311323", "32311321", "21411322", "24111412", + "13211413", "33211411", "22311412", "11411413", "31411411", + "24211141", "13311142", "22411141", "11511142", "25111231", + "14211232", "23311231", "12411232", "21511231", "15111322", + "24211321", "13311322", "22411321", "11511322", "25111411", + "14211412", "23311411", "12411412", "21511411", "14311141", + "12511141", "15211231", "13411231", "11611231", "16111321", + "14311321", "12511321", "15211411", "13411411", "11611411", + "31121143", "51121141", "21112144", "41112142", "21121234", + "41121232", "11112235", "31112233", "51112231", "11121325", + "31121323", "51121321", "21112324", "41112322", "21121414", + "41121412", + /* Column 30 */ + "11112415", "31112413", "51112411", "12121144", + "32121142", "21221143", "41221141", "22112143", "42112141", + "11212144", "22121233", "42121231", "11221234", "31221232", + "12112234", "32112232", "12121324", "32121322", "21221323", + "41221321", "22112323", "42112321", "11212324", "22121413", + "42121411", "11221414", "31221412", "12112414", "32112412", + "21212413", "41212411", "13121143", "33121141", "22221142", + "11321143", "31321141", "23112142", "12212143", "23121232", + "12221233", "32221231", "21321232", "13112233", "33112231", + "13121323", "33121321", "11312233", "22221322", "11321323", + "31321321", "23112322", "12212323", "23121412", "12221413", + "32221411", "21321412", "13112413", "33112411", + /* Column 31 */ + "22212412", + "11312413", "31312411", "14121142", "23221141", "12321142", + "21421141", "24112141", "13212142", "24121231", "13221232", + "11412142", "22321231", "11421232", "14112232", "14121322", + "12312232", "23221321", "12321322", "21421321", "24112321", + "13212322", "24121411", "13221412", "11412322", "22321411", + "11421412", "14112412", "23212411", "12312412", "21412411", + "15121141", "13321141", "11521141", "14212141", "14221231", + "12412141", "12421231", "15112231", "15121321", "13312231", + "13321321", "11512231", "11521321", "14212321", "14221411", + "12412321", "12421411", "15112411", "13312411", "11512411", + "11131144", "31131142", "21122143", "41122141", "21131233", + "41131231", "11113144", + /* Column 32 */ + "31113142", "11122234", "31122232", + "11131324", "31131322", "21113233", "41113231", "21122323", + "41122321", "21131413", "41131411", "11113324", "31113322", + "11122414", "31122412", "21113413", "41113411", "12131143", + "32131141", "21231142", "22122142", "11222143", "22131232", + "11231233", "31231231", "12113143", "32113141", "12122233", + "32122231", "12131323", "32131321", "21231322", "22113232", + "11213233", "22122322", "11222323", "22131412", "11231413", + "31231411", "12113323", "32113321", "12122413", "32122411", + "21222412", "22113412", "11213413", "31213411", "13131142", + "22231141", "11331142", "23122141", "12222142", "23131231", + "12231232", "21331231", "13113142", "13122232", "11313142", + /* Column 33 */ + "13131322", "11322232", "22231321", "11331322", "23113231", + "12213232", "23122321", "12222322", "23131411", "12231412", + "21331411", "13113322", "13122412", "11313322", "22222411", + "11322412", "23113411", "12213412", "21313411", "14131141", + "12331141", "13222141", "13231231", "11422141", "11431231", + "14113141", "14122231", "12313141", "14131321", "12322231", + "12331321", "13213231", "13222321", "11413231", "13231411", + "11422321", "11431411", "14113321", "14122411", "12313321", + "12322411", "13213411", "11413411", "11141143", "31141141", + "21132142", "21141232", "11123143", "31123141", "11132233", + "31132231", "11141323", "31141321", "21114142", "21123232", + "21132322", "21141412", "11114233", + /* Column 34 */ + "31114231", "11123323", + "31123321", "11132413", "31132411", "21114322", "21123412", + "12141142", "21241141", "22132141", "11232142", "22141231", + "11241232", "12123142", "12132232", "12141322", "21241321", + "22114141", "11214142", "22123231", "11223232", "22132321", + "11232322", "22141411", "11241412", "12114232", "12123322", + "12132412", "21232411", "22114321", "11214322", "22123411", + "11223412", "13141141", "11341141", "12232141", "12241231", + "13123141", "13132231", "11323141", "13141321", "11332231", + "11341321", "12214141", "12223231", "12232321", "12241411", + "13114231", "13123321", "11314231", "13132411", "11323321", + "11332411", "12214321", "12223411", "11151142", "21142141", + "21151231", + /* Column 35 */ + "11133142", "11142232", "11151322", "21124141", + "21133231", "21142321", "21151411", "11115142", "11124232", + "11133322", "11142412", "21115231", "21124321", "21133411", + "12151141", "11242141", "11251231", "12133141", "12142231", + "12151321", "11224141", "11233231", "11242321", "11251411", + "12115141", "12124231", "12133321", "12142411", "11215231", + "11224321", "11233411", "11161141", "11143141", "11152231", + "11161321", "11125141", "11134231", "11143321", "11152411", + "11111245", "31111243", "51111241", "21111334", "41111332", + "11111425", "31111423", "51111421", "21111514", "41111512", + "31211152", "12111244", "32111242", "21211243", "41211241", + "22111333", "42111331", "11211334", "31211332", + /* Column 36 */ + "12111424", + "32111422", "21211423", "41211421", "22111513", "42111511", + "11211514", "31211512", "12211153", "32211151", "21311152", + "13111243", "33111241", "22211242", "11311243", "31311241", + "23111332", "12211333", "32211331", "21311332", "13111423", + "33111421", "22211422", "11311423", "31311421", "23111512", + "12211513", "32211511", "21311512", "13211152", "22311151", + "11411152", "14111242", "23211241", "12311242", "21411241", + "24111331", "13211332", "22311331", "11411332", "14111422", + "23211421", "12311422", "21411421", "24111511", "13211512", + "22311511", "11411512", "14211151", "12411151", "15111241", + "13311241", "11511241", "14211331", "12411331", "15111421", + "13311421", "11511421", + /* Column 37 */ + "14211511", "12411511", "21121153", + "41121151", "11112154", "31112152", "11121244", "31121242", + "21112243", "41112241", "21121333", "41121331", "11112334", + "31112332", "11121424", "31121422", "21112423", "41112421", + "21121513", "41121511", "11112514", "31112512", "22121152", + "11221153", "31221151", "12112153", "32112151", "12121243", + "32121241", "21221242", "22112242", "11212243", "22121332", + "11221333", "31221331", "12112333", "32112331", "12121423", + "32121421", "21221422", "22112422", "11212423", "22121512", + "11221513", "31221511", "12112513", "32112511", "21212512", + "23121151", "12221152", "21321151", "13112152", "13121242", + "11312152", "22221241", "11321242", "23112241", "12212242", + /* Column 38 */ + "23121331", "12221332", "21321331", "13112332", "13121422", + "11312332", "22221421", "11321422", "23112421", "12212422", + "23121511", "12221512", "21321511", "13112512", "22212511", + "11312512", "13221151", "11421151", "14112151", "14121241", + "12312151", "12321241", "13212241", "13221331", "11412241", + "11421331", "14112331", "14121421", "12312331", "12321421", + "13212421", "13221511", "11412421", "11421511", "14112511", + "12312511", "21131152", "11122153", "31122151", "11131243", + "31131241", "21113152", "21122242", "21131332", "11113243", + "31113241", "11122333", "31122331", "11131423", "31131421", + "21113332", "21122422", "21131512", "11113423", "31113421", + "11122513", "31122511", "22131151", + /* Column 39 */ + "11231152", "12122152", + "12131242", "21231241", "22113151", "11213152", "22122241", + "11222242", "22131331", "11231332", "12113242", "12122332", + "12131422", "21231421", "22113331", "11213332", "22122421", + "11222422", "22131511", "11231512", "12113422", "12122512", + "21222511", "12231151", "13122151", "13131241", "11322151", + "11331241", "12213151", "12222241", "12231331", "13113241", + "13122331", "11313241", "13131421", "11322331", "11331421", + "12213331", "12222421", "12231511", "13113421", "13122511", + "11313421", "11322511", "21141151", "11132152", "11141242", + "21123151", "21132241", "21141331", "11114152", "11123242", + "11132332", "11141422", "21114241", "21123331", "21132421", + "21141511", + /* Column 40 */ + "11114332", "11123422", "11132512", "11241151", + "12132151", "12141241", "11223151", "11232241", "11241331", + "12114151", "12123241", "12132331", "12141421", "11214241", + "11223331", "11232421", "11241511", "12114331", "12123421", + "12132511", "11142151", "11151241", "11124151", "11133241", + "11142331", "11151421", "11115241", "11124331", "11133421", + "11142511", "21111253", "41111251", "11111344", "31111342", + "21111433", "41111431", "11111524", "31111522", "21111613", + "41111611", "21211162", "22111252", "11211253", "31211251", + "12111343", "32111341", "21211342", "22111432", "11211433", + "31211431", "12111523", "32111521", "21211522", "22111612", + "11211613", "31211611", "22211161", "11311162", + /* Column 41 */ + "23111251", + "12211252", "21311251", "13111342", "22211341", "11311342", + "23111431", "12211432", "21311431", "13111522", "22211521", + "11311522", "23111611", "12211612", "21311611", "12311161", + "13211251", "11411251", "14111341", "12311341", "13211431", + "11411431", "14111521", "12311521", "13211611", "11411611", + "31121161", "21112162", "21121252", "11112253", "31112251", + "11121343", "31121341", "21112342", "21121432", "11112433", + "31112431", "11121523", "31121521", "21112522", "21121612", + /* Column 42 */ + "12121162", "21221161", "22112161", "11212162", "22121251", + "11221252", "12112252", "12121342", "21221341", "22112341", + "11212342", "22121431", "11221432", "12112432", "12121522", + "21221521", "22112521", "11212522", "22121611", "11221612", + "13121161", "11321161", "12212161", "12221251", "13112251", + "13121341", "11312251", "11321341", "12212341", "12221431", + "13112431", "13121521", "11312431", "11321521", "12212521", + "12221611", "11131162", "21122161", "21131251", "11113162" +}; diff --git a/backend/common.c b/backend/common.c new file mode 100644 index 00000000..e7ed58a6 --- /dev/null +++ b/backend/common.c @@ -0,0 +1,397 @@ +/* common.c - Contains functions needed for a number of barcodes */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include +#include "common.h" + +int ustrlen(unsigned char data[]) { + /* Local replacement for strlen() with unsigned char strings */ + int i; + for (i=0;data[i];i++); + + return i; +} + +void ustrcpy(unsigned char target[], unsigned char source[]) { + /* Local replacement for strcpy() with unsigned char strings */ + int i, len; + + len = ustrlen(source); + for(i = 0; i < len; i++) { + target[i] = source[i]; + } + target[i] = '\0'; +} + +void concat(char dest[], char source[]) +{ /* Concatinates dest[] with the contents of source[], copying /0 as well */ + unsigned int i, j, n; + + j = strlen(dest); + n = strlen(source); + for(i = 0; i <= n; i++) { + dest[i + j] = source[i]; } +} + +void uconcat(unsigned char dest[], unsigned char source[]) +{ /* Concatinates dest[] with the contents of source[], copying /0 as well */ + unsigned int i, j; + + j = ustrlen(dest); + for(i = 0; i <= ustrlen(source); i++) { + dest[i + j] = source[i]; } +} + + +int ctoi(char source) +{ /* Converts a character 0-9 to its equivalent integer value */ + if((source >= '0') && (source <= '9')) + return (source - '0'); + return(source - 'A' + 10); +} + +char itoc(int source) +{ /* Converts an integer value to its hexadecimal character */ + if ((source >= 0) && (source <= 9)) { + return ('0' + source); } + else { + return ('A' + (source - 10)); } +} + +void to_upper(unsigned char source[]) +{ /* Converts lower case characters to upper case in a string source[] */ + unsigned int i, src_len = ustrlen(source); + + for (i = 0; i < src_len; i++) { + if ((source[i] >= 'a') && (source[i] <= 'z')) { + source [i] = (source[i] - 'a') + 'A'; } + } +} + +int is_sane(char test_string[], unsigned char source[], int length) +{ /* Verifies that a string only uses valid characters */ + unsigned int i, j, latch; + unsigned int lt = strlen(test_string); + + for(i = 0; i < length; i++) { + latch = FALSE; + for(j = 0; j < lt; j++) { + if (source[i] == test_string[j]) { + latch = TRUE; + break; + } + } + if (!(latch)) { + return ERROR_INVALID_DATA; + } + } + + return 0; +} + +int posn(char set_string[], char data) +{ /* Returns the position of data in set_string */ + unsigned int i, n = strlen(set_string); + + for(i = 0; i < n; i++) { + if (data == set_string[i]) { return i; } } + return 0; +} + +void lookup(char set_string[], char *table[], char data, char dest[]) +{ /* Replaces huge switch statements for looking up in tables */ + unsigned int i, n = strlen(set_string); + + for(i = 0; i < n; i++) { + if (data == set_string[i]) { concat(dest, table[i]); } } +} + +int module_is_set(struct zint_symbol *symbol, int y_coord, int x_coord) +{ + return (symbol->encoded_data[y_coord][x_coord / 7] & (1 << (x_coord % 7))) ? 1 : 0; +#if 0 + switch(x_sub) { + case 0: if((symbol->encoded_data[y_coord][x_char] & 0x01) != 0) { result = 1; } break; + case 1: if((symbol->encoded_data[y_coord][x_char] & 0x02) != 0) { result = 1; } break; + case 2: if((symbol->encoded_data[y_coord][x_char] & 0x04) != 0) { result = 1; } break; + case 3: if((symbol->encoded_data[y_coord][x_char] & 0x08) != 0) { result = 1; } break; + case 4: if((symbol->encoded_data[y_coord][x_char] & 0x10) != 0) { result = 1; } break; + case 5: if((symbol->encoded_data[y_coord][x_char] & 0x20) != 0) { result = 1; } break; + case 6: if((symbol->encoded_data[y_coord][x_char] & 0x40) != 0) { result = 1; } break; + } + + return result; +#endif +} + +void set_module(struct zint_symbol *symbol, int y_coord, int x_coord) +{ + if(module_is_set(symbol, y_coord, x_coord)) { return; } + symbol->encoded_data[y_coord][x_coord / 7] += 1 << (x_coord % 7); +#if 0 + int x_char, x_sub; + + + x_char = x_coord / 7; + x_sub = x_coord % 7; + + switch(x_sub) { + case 0: symbol->encoded_data[y_coord][x_char] += 0x01; break; + case 1: symbol->encoded_data[y_coord][x_char] += 0x02; break; + case 2: symbol->encoded_data[y_coord][x_char] += 0x04; break; + case 3: symbol->encoded_data[y_coord][x_char] += 0x08; break; + case 4: symbol->encoded_data[y_coord][x_char] += 0x10; break; + case 5: symbol->encoded_data[y_coord][x_char] += 0x20; break; + case 6: symbol->encoded_data[y_coord][x_char] += 0x40; break; + } /* The last binary digit is reserved for colour barcodes */ +#endif +} + +void unset_module(struct zint_symbol *symbol, int y_coord, int x_coord) +{ + if(!(module_is_set(symbol, y_coord, x_coord))) { return; } + symbol->encoded_data[y_coord][x_coord / 7] -= 1 << (x_coord % 7); +#if 0 + int x_char, x_sub; + + x_char = x_coord / 7; + x_sub = x_coord % 7; + + switch(x_sub) { + case 0: symbol->encoded_data[y_coord][x_char] -= 0x01; break; + case 1: symbol->encoded_data[y_coord][x_char] -= 0x02; break; + case 2: symbol->encoded_data[y_coord][x_char] -= 0x04; break; + case 3: symbol->encoded_data[y_coord][x_char] -= 0x08; break; + case 4: symbol->encoded_data[y_coord][x_char] -= 0x10; break; + case 5: symbol->encoded_data[y_coord][x_char] -= 0x20; break; + case 6: symbol->encoded_data[y_coord][x_char] -= 0x40; break; + } /* The last binary digit is reserved for colour barcodes */ +#endif +} + +void expand(struct zint_symbol *symbol, char data[]) +{ /* Expands from a width pattern to a bit pattern */ + + unsigned int reader, n = strlen(data); + int writer, i; + char latch; + + writer = 0; + latch = '1'; + + for(reader = 0; reader < n; reader++) { + for(i = 0; i < ctoi(data[reader]); i++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + + if(symbol->symbology != BARCODE_PHARMA) { + if(writer > symbol->width) { + symbol->width = writer; + } + } else { + /* Pharmacode One ends with a space - adjust for this */ + if(writer > symbol->width + 2) { + symbol->width = writer - 2; + } + } + symbol->rows = symbol->rows + 1; +} + +int is_stackable(int symbology) { + /* Indicates which symbologies can have row binding */ + if(symbology < BARCODE_PDF417) { return 1; } + if(symbology == BARCODE_CODE128B) { return 1; } + if(symbology == BARCODE_ISBNX) { return 1; } + if(symbology == BARCODE_EAN14) { return 1; } + if(symbology == BARCODE_NVE18) { return 1; } + if(symbology == BARCODE_KOREAPOST) { return 1; } + if(symbology == BARCODE_PLESSEY) { return 1; } + if(symbology == BARCODE_TELEPEN_NUM) { return 1; } + if(symbology == BARCODE_ITF14) { return 1; } + if(symbology == BARCODE_CODE32) { return 1; } + + return 0; +} + +int is_extendable(int symbology) { + /* Indicates which symbols can have addon */ + if(symbology == BARCODE_EANX) { return 1; } + if(symbology == BARCODE_UPCA) { return 1; } + if(symbology == BARCODE_UPCE) { return 1; } + if(symbology == BARCODE_ISBNX) { return 1; } + if(symbology == BARCODE_UPCA_CC) { return 1; } + if(symbology == BARCODE_UPCE_CC) { return 1; } + if(symbology == BARCODE_EANX_CC) { return 1; } + + return 0; +} + +int roundup(float input) +{ + float remainder; + int integer_part; + + integer_part = (int)input; + remainder = input - integer_part; + + if(remainder > 0.1) { + integer_part++; + } + + return integer_part; +} + +int istwodigits(unsigned char source[], int position) +{ + if((source[position] >= '0') && (source[position] <= '9')) { + if((source[position + 1] >= '0') && (source[position + 1] <= '9')) { + return 1; + } + } + + return 0; +} + +float froundup(float input) +{ + float fraction, output = 0.0; + + fraction = input - (int)input; + if(fraction > 0.01) { output = (input - fraction) + 1.0; } else { output = input; } + + return output; +} + +int latin1_process(struct zint_symbol *symbol, unsigned char source[], unsigned char preprocessed[], int *length) +{ + int j, i, next; + + /* Convert Unicode to Latin-1 for those symbologies which only support Latin-1 */ + j = 0; + i = 0; + do { + next = -1; + if(source[i] < 128) { + preprocessed[j] = source[i]; + j++; + next = i + 1; + } else { + if(source[i] == 0xC2) { + preprocessed[j] = source[i + 1]; + j++; + next = i + 2; + } + if(source[i] == 0xC3) { + preprocessed[j] = source[i + 1] + 64; + j++; + next = i + 2; + } + } + if(next == -1) { + strcpy(symbol->errtxt, "error: Invalid character in input string (only Latin-1 characters supported)"); + return ERROR_INVALID_DATA; + } + i = next; + } while(i < *length); + preprocessed[j] = '\0'; + *length = j; + + return 0; +} + +int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length) +{ + int bpos, jpos, error_number, done; + int next; + + bpos = 0; + jpos = 0; + error_number = 0; + next = 0; + + do { + done = 0; + + if(source[bpos] <= 0x7f) { + /* 1 byte mode (7-bit ASCII) */ + vals[jpos] = source[bpos]; + next = bpos + 1; + jpos++; + done = 1; + } + + if(done == 0) { + if((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) { + strcpy(symbol->errtxt, "Corrupt Unicode data"); + return ERROR_INVALID_DATA; + } + } + + if(done == 0) { + if((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) { + strcpy(symbol->errtxt, "Overlong encoding not supported"); + return ERROR_INVALID_DATA; + } + } + + if(done == 0) { + if((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) { + /* 2 byte mode */ + vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f); + next = bpos + 2; + jpos++; + done = 1; + } + } + + if(done == 0) { + if((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) { + /* 3 byte mode */ + vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f); + next = bpos + 3; + jpos ++; + done = 1; + } + } + + if(done == 0) { + if(source[bpos] >= 0xf0) { + strcpy(symbol->errtxt, "Unicode sequences of more than 3 bytes not supported"); + return ERROR_INVALID_DATA; + } + } + + bpos = next; + + } while(bpos < *length); + *length = jpos; + + return error_number; +} + diff --git a/backend/common.h b/backend/common.h new file mode 100644 index 00000000..52bc9117 --- /dev/null +++ b/backend/common.h @@ -0,0 +1,70 @@ +/* common.h - Header for all common functions in common.c */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +/* Used in some logic */ +#ifndef __COMMON_H +#define __COMMON_H + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +/* The most commonly used set */ +#define NEON "0123456789" + +#include "zint.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +extern int ustrlen(unsigned char source[]); +extern void ustrcpy(unsigned char target[], unsigned char source[]); +extern void concat(char dest[], char source[]); +extern void uconcat(unsigned char dest[], unsigned char source[]); +extern int ctoi(char source); +extern char itoc(int source); +extern void to_upper(unsigned char source[]); +extern int is_sane(char test_string[], unsigned char source[], int length); +extern void lookup(char set_string[], char *table[], char data, char dest[]); +extern int posn(char set_string[], char data); +extern void expand(struct zint_symbol *symbol, char data[]); +extern int is_stackable(int symbology); +extern int is_extendable(int symbology); +extern int roundup(float input); +extern int module_is_set(struct zint_symbol *symbol, int y_coord, int x_coord); +extern void set_module(struct zint_symbol *symbol, int y_coord, int x_coord); +extern void unset_module(struct zint_symbol *symbol, int y_coord, int x_coord); +extern int istwodigits(unsigned char source[], int position); +extern float froundup(float input); +extern int parunmodd(unsigned char llyth); +extern int latin1_process(struct zint_symbol *symbol, unsigned char source[], unsigned char preprocessed[], int *length); +extern int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __COMMON_H */ diff --git a/backend/composite.c b/backend/composite.c new file mode 100644 index 00000000..82f3360e --- /dev/null +++ b/backend/composite.c @@ -0,0 +1,1954 @@ +/* composite.c - Handles UCC.EAN Composite Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* The functions "getBit", "init928" and "encode928" are copyright BSI and are + released with permission under the following terms: + + "Copyright subsists in all BSI publications. BSI also holds the copyright, in the + UK, of the international standardisation bodies. Except as + permitted under the Copyright, Designs and Patents Act 1988 no extract may be + reproduced, stored in a retrieval system or transmitted in any form or by any + means - electronic, photocopying, recording or otherwise - without prior written + permission from BSI. + + "This does not preclude the free use, in the course of implementing the standard, + of necessary details such as symbols, and size, type or grade designations. If these + details are to be used for any other purpose than implementation then the prior + written permission of BSI must be obtained." + + The date of publication for these functions is 31 May 2006 +*/ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "large.h" +#include "composite.h" +#include "pdf417.h" +#include "gs1.h" + +#define UINT unsigned short + +extern int general_rules(char field[], char type[]); +extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); +extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); +extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); +extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); +extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); + +static UINT pwr928[69][7]; + +int _min(int first, int second) { + + if(first <= second) + return first; + else + return second; +} + +/* gets bit in bitString at bitPos */ +int getBit(UINT *bitStr, int bitPos) { + return(((bitStr[bitPos/16] & (0x8000>>(bitPos%16))) == 0) ? 0 : 1); +} + +/* initialize pwr928 encoding table */ +void init928(void) { + int i, j, v; + int cw[7]; + cw[6] = 1L; + for (i = 5; i >= 0; i--) + cw[i] = 0; + + for (i = 0; i < 7; i++) + pwr928[0][i] = cw[i]; + for (j = 1; j < 69; j++) { + for (v = 0, i = 6; i >= 1; i--) { + v = (2 * cw[i]) + (v / 928); + pwr928[j][i] = cw[i] = v % 928; + } + pwr928[j][0] = cw[0] = (2 * cw[0]) + (v / 928); + } + return; +} + +/* converts bit string to base 928 values, codeWords[0] is highest order */ +int encode928(UINT bitString[], UINT codeWords[], int bitLng) { + int i, j, b, bitCnt, cwNdx, cwCnt, cwLng; + for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) { + bitCnt = _min(bitLng-b, 69); + cwLng += cwCnt = bitCnt/10 + 1; + for (i = 0; i < cwCnt; i++) + codeWords[cwNdx+i] = 0; /* init 0 */ + for (i = 0; i < bitCnt; i++) { + if (getBit(bitString, b+bitCnt-i-1)) { + for (j = 0; j < cwCnt; j++) + codeWords[cwNdx+j] += pwr928[i][j+7-cwCnt]; + } + } + for (i = cwCnt-1; i > 0; i--) { + /* add "carries" */ + codeWords[cwNdx+i-1] += codeWords[cwNdx+i]/928L; + codeWords[cwNdx+i] %= 928L; + } + } + return (cwLng); +} + +int cc_a(struct zint_symbol *symbol, char source[], int cc_width) +{ /* CC-A 2D component */ + int i, strpos, segment, bitlen, cwCnt, variant, rows; + int k, offset, j, total, rsCodeWords[8]; + int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; + int LeftRAP, RightRAP, CentreRAP, Cluster, dummy[5]; + int writer, flip, loop; + UINT codeWords[28]; + UINT bitStr[13]; + char codebarre[100], pattern[580]; + char local_source[210]; /* A copy of source but with padding zeroes to make 208 bits */ + + variant=0; + + for(i = 0; i < 13; i++) { bitStr[i] = 0; } + for(i = 0; i < 28; i++) { codeWords[i] = 0; } + + bitlen = strlen(source); + + for(i = 0; i < 208; i++) { local_source[i] = '0'; } + for(i = 0; i < bitlen; i++) { local_source[i] = source[i]; } + local_source[208] = '\0'; + + for(segment = 0; segment < 13; segment++) { + strpos = segment * 16; + if(local_source[strpos] == '1') { bitStr[segment] += 0x8000; } + if(local_source[strpos + 1] == '1') { bitStr[segment] += 0x4000; } + if(local_source[strpos + 2] == '1') { bitStr[segment] += 0x2000; } + if(local_source[strpos + 3] == '1') { bitStr[segment] += 0x1000; } + if(local_source[strpos + 4] == '1') { bitStr[segment] += 0x800; } + if(local_source[strpos + 5] == '1') { bitStr[segment] += 0x400; } + if(local_source[strpos + 6] == '1') { bitStr[segment] += 0x200; } + if(local_source[strpos + 7] == '1') { bitStr[segment] += 0x100; } + if(local_source[strpos + 8] == '1') { bitStr[segment] += 0x80; } + if(local_source[strpos + 9] == '1') { bitStr[segment] += 0x40; } + if(local_source[strpos + 10] == '1') { bitStr[segment] += 0x20; } + if(local_source[strpos + 11] == '1') { bitStr[segment] += 0x10; } + if(local_source[strpos + 12] == '1') { bitStr[segment] += 0x08; } + if(local_source[strpos + 13] == '1') { bitStr[segment] += 0x04; } + if(local_source[strpos + 14] == '1') { bitStr[segment] += 0x02; } + if(local_source[strpos + 15] == '1') { bitStr[segment] += 0x01; } + } + + init928(); + /* encode codeWords from bitStr */ + cwCnt = encode928(bitStr, codeWords, bitlen); + + switch(cc_width) { + case 2: + switch(cwCnt) { + case 6: variant = 0; break; + case 8: variant = 1; break; + case 9: variant = 2; break; + case 11: variant = 3; break; + case 12: variant = 4; break; + case 14: variant = 5; break; + case 17: variant = 6; break; + } + break; + case 3: + switch(cwCnt) { + case 8: variant = 7; break; + case 10: variant = 8; break; + case 12: variant = 9; break; + case 14: variant = 10; break; + case 17: variant = 11; break; + } + break; + case 4: + switch(cwCnt) { + case 8: variant = 12; break; + case 11: variant = 13; break; + case 14: variant = 14; break; + case 17: variant = 15; break; + case 20: variant = 16; break; + } + break; + } + + rows = ccaVariants[variant]; + k = ccaVariants[17 + variant]; + offset = ccaVariants[34 + variant]; + + /* Reed-Solomon error correction */ + + for(i = 0; i < 8; i++) { + rsCodeWords[i] = 0; + } + total = 0; + for(i = 0; i < cwCnt; i++) { + total = (codeWords[i] + rsCodeWords[k - 1]) % 929; + for(j = k - 1; j >= 0; j--) { + if(j == 0) { + rsCodeWords[j] = (929 - (total * ccaCoeffs[offset + j]) % 929) % 929; + } else { + rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * ccaCoeffs[offset + j]) % 929) % 929; + } + } + } + + for(j = 0; j < k; j++) { + if(rsCodeWords[j] != 0) { rsCodeWords[j] = 929 - rsCodeWords[j]; } + } + + for(i = k - 1; i >= 0; i--) { + codeWords[cwCnt] = rsCodeWords[i]; + cwCnt++; + } + + /* Place data into table */ + LeftRAPStart = aRAPTable[variant]; + CentreRAPStart = aRAPTable[variant + 17]; + RightRAPStart = aRAPTable[variant + 34]; + StartCluster = aRAPTable[variant + 51] / 3; + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + for(i = 0; i < rows; i++) { + strcpy(codebarre, ""); + offset = 929 * Cluster; + for(j = 0; j < 5; j++) { + dummy[j] = 0; + } + for(j = 0; j < cc_width ; j++) { + dummy[j + 1] = codeWords[i * cc_width + j]; + } + /* Copy the data into codebarre */ + concat(codebarre, RAPLR[LeftRAP]); + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[1]]); + concat(codebarre, "1"); + if(cc_width >= 2) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[2]]); + concat(codebarre, "1"); + } + if(CentreRAPStart != 0) { + concat(codebarre, RAPC[CentreRAP]); + } + if(cc_width >= 3) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[3]]); + concat(codebarre, "1"); + } + if(cc_width == 4) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[4]]); + concat(codebarre, "1"); + } + concat(codebarre, RAPLR[RightRAP]); + concat(codebarre, "1"); /* stop */ + + /* Now codebarre is a mixture of letters and numbers */ + + writer = 0; + flip = 1; + strcpy(pattern, ""); + for(loop = 0; loop < strlen(codebarre); loop++) { + if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { + for(k = 0; k < ctoi(codebarre[loop]); k++) { + if(flip == 0) { + pattern[writer] = '0'; + } else { + pattern[writer] = '1'; + } + writer++; + } + pattern[writer] = '\0'; + if(flip == 0) { + flip = 1; + } else { + flip = 0; + } + } else { + lookup(BRSET, PDFttf, codebarre[loop], pattern); + writer += 5; + } + } + symbol->width = writer; + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for(loop = 0; loop < strlen(pattern); loop++) { + if(pattern[loop] == '1') { set_module(symbol, i, loop); } + } + symbol->row_height[i] = 2; + symbol->rows++; + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if(LeftRAP == 53) { + LeftRAP = 1; + } + if(CentreRAP == 53) { + CentreRAP = 1; + } + if(RightRAP == 53) { + RightRAP = 1; + } + if(Cluster == 3) { + Cluster = 0; + } + } + + return 0; +} + +int cc_b(struct zint_symbol *symbol, char source[], int cc_width) +{ /* CC-B 2D component */ + int length, i, binloc; +#ifndef _MSC_VER + unsigned char data_string[(strlen(source) / 8) + 3]; +#else + unsigned char* data_string = (unsigned char*)_alloca((strlen(source) / 8) + 3); +#endif + int chainemc[180], mclength; + int k, j, longueur, mccorrection[50], offset; + int total, dummy[5]; + char codebarre[100], pattern[580]; + int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; + int LeftRAP, CentreRAP, RightRAP, Cluster, writer, flip, loop; + + length = strlen(source) / 8; + + for(i = 0; i < length; i++) { + binloc = i * 8; + + data_string[i] = 0; + if(source[binloc] == '1') { data_string[i] += 0x80; } + if(source[binloc + 1] == '1') { data_string[i] += 0x40; } + if(source[binloc + 2] == '1') { data_string[i] += 0x20; } + if(source[binloc + 3] == '1') { data_string[i] += 0x10; } + if(source[binloc + 4] == '1') { data_string[i] += 0x08; } + if(source[binloc + 5] == '1') { data_string[i] += 0x04; } + if(source[binloc + 6] == '1') { data_string[i] += 0x02; } + if(source[binloc + 7] == '1') { data_string[i] += 0x01; } + } + + + mclength = 0; + + /* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */ + chainemc[mclength] = 920; + mclength++; + + byteprocess(chainemc, &mclength, data_string, 0, length, 0); + + /* Now figure out which variant of the symbol to use and load values accordingly */ + + variant = 0; + + if(cc_width == 2) { + variant = 13; + if(mclength <= 33) { variant = 12; } + if(mclength <= 29) { variant = 11; } + if(mclength <= 24) { variant = 10; } + if(mclength <= 19) { variant = 9; } + if(mclength <= 13) { variant = 8; } + if(mclength <= 8) { variant = 7; } + } + + if(cc_width == 3) { + variant = 23; + if(mclength <= 70) { variant = 22; } + if(mclength <= 58) { variant = 21; } + if(mclength <= 46) { variant = 20; } + if(mclength <= 34) { variant = 19; } + if(mclength <= 24) { variant = 18; } + if(mclength <= 18) { variant = 17; } + if(mclength <= 14) { variant = 16; } + if(mclength <= 10) { variant = 15; } + if(mclength <= 6) { variant = 14; } + } + + if(cc_width == 4) { + variant = 34; + if(mclength <= 108) { variant = 33; } + if(mclength <= 90) { variant = 32; } + if(mclength <= 72) { variant = 31; } + if(mclength <= 54) { variant = 30; } + if(mclength <= 39) { variant = 29; } + if(mclength <= 30) { variant = 28; } + if(mclength <= 24) { variant = 27; } + if(mclength <= 18) { variant = 26; } + if(mclength <= 12) { variant = 25; } + if(mclength <= 8) { variant = 24; } + } + + /* Now we have the variant we can load the data - from here on the same as MicroPDF417 code */ + variant --; + symbol->option_2 = MicroVariants[variant]; /* columns */ + symbol->rows = MicroVariants[variant + 34]; /* rows */ + k = MicroVariants[variant + 68]; /* number of EC CWs */ + longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ + i = longueur - mclength; /* amount of padding required */ + offset = MicroVariants[variant + 102]; /* coefficient offset */ + + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + + /* Reed-Solomon error correction */ + longueur = mclength; + for(loop = 0; loop < 50; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for(i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for(j = k - 1; j >= 0; j--) { + if(j == 0) { + mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } + } + } + + for(j = 0; j < k; j++) { + if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } + } + /* we add these codes to the string */ + for(i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + /* Now get the RAP (Row Address Pattern) start values */ + LeftRAPStart = RAPTable[variant]; + CentreRAPStart = RAPTable[variant + 34]; + RightRAPStart = RAPTable[variant + 68]; + StartCluster = RAPTable[variant + 102] / 3; + + /* That's all values loaded, get on with the encoding */ + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + for(i = 0; i < symbol->rows; i++) { + strcpy(codebarre, ""); + offset = 929 * Cluster; + for(j = 0; j < 5; j++) { + dummy[j] = 0; + } + for(j = 0; j < symbol->option_2 ; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + } + /* Copy the data into codebarre */ + concat(codebarre, RAPLR[LeftRAP]); + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[1]]); + concat(codebarre, "1"); + if(cc_width == 3) { + concat(codebarre, RAPC[CentreRAP]); + } + if(cc_width >= 2) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[2]]); + concat(codebarre, "1"); + } + if(cc_width == 4) { + concat(codebarre, RAPC[CentreRAP]); + } + if(cc_width >= 3) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[3]]); + concat(codebarre, "1"); + } + if(cc_width == 4) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[4]]); + concat(codebarre, "1"); + } + concat(codebarre, RAPLR[RightRAP]); + concat(codebarre, "1"); /* stop */ + + /* Now codebarre is a mixture of letters and numbers */ + + writer = 0; + flip = 1; + strcpy(pattern, ""); + for(loop = 0; loop < strlen(codebarre); loop++) { + if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { + for(k = 0; k < ctoi(codebarre[loop]); k++) { + if(flip == 0) { + pattern[writer] = '0'; + } else { + pattern[writer] = '1'; + } + writer++; + } + pattern[writer] = '\0'; + if(flip == 0) { + flip = 1; + } else { + flip = 0; + } + } else { + lookup(BRSET, PDFttf, codebarre[loop], pattern); + writer += 5; + } + } + symbol->width = writer; + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for(loop = 0; loop < strlen(pattern); loop++) { + if(pattern[loop] == '1') { set_module(symbol, i, loop); } + } + symbol->row_height[i] = 2; + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if(LeftRAP == 53) { + LeftRAP = 1; + } + if(CentreRAP == 53) { + CentreRAP = 1; + } + if(RightRAP == 53) { + RightRAP = 1; + } + if(Cluster == 3) { + Cluster = 0; + } + } + + return 0; +} + +int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) +{ /* CC-C 2D component - byte compressed PDF417 */ + int length, i, binloc; +#ifndef _MSC_VER + unsigned char data_string[(strlen(source) / 8) + 4]; +#else + unsigned char* data_string = (unsigned char*)_alloca((strlen(source) / 8) + 4); +#endif + int chainemc[1000], mclength, k; + int offset, longueur, loop, total, j, mccorrection[520]; + int c1, c2, c3, dummy[35]; + char codebarre[100], pattern[580]; + + length = strlen(source) / 8; + + for(i = 0; i < length; i++) { + binloc = i * 8; + + data_string[i] = 0; + if(source[binloc] == '1') { data_string[i] += 0x80; } + if(source[binloc + 1] == '1') { data_string[i] += 0x40; } + if(source[binloc + 2] == '1') { data_string[i] += 0x20; } + if(source[binloc + 3] == '1') { data_string[i] += 0x10; } + if(source[binloc + 4] == '1') { data_string[i] += 0x08; } + if(source[binloc + 5] == '1') { data_string[i] += 0x04; } + if(source[binloc + 6] == '1') { data_string[i] += 0x02; } + if(source[binloc + 7] == '1') { data_string[i] += 0x01; } + } + + mclength = 0; + + chainemc[mclength] = 0; /* space for length descriptor */ + mclength++; + chainemc[mclength] = 920; /* CC-C identifier */ + mclength++; + + byteprocess(chainemc, &mclength, data_string, 0, length, 0); + + chainemc[0] = mclength; + + k = 1; + for(i = 1; i <= (ecc_level + 1); i++) + { + k *= 2; + } + + /* 796 - we now take care of the Reed Solomon codes */ + switch(ecc_level) { + case 1: offset = 2; break; + case 2: offset = 6; break; + case 3: offset = 14; break; + case 4: offset = 30; break; + case 5: offset = 62; break; + case 6: offset = 126; break; + case 7: offset = 254; break; + case 8: offset = 510; break; + default: offset = 0; break; + } + + longueur = mclength; + for(loop = 0; loop < 520; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for(i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for(j = k - 1; j >= 0; j--) { + if(j == 0) { + mccorrection[j] = (929 - (total * coefrs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; + } + } + } + + for(j = 0; j < k; j++) { + if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } + } + /* we add these codes to the string */ + for(i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + /* 818 - The CW string is finished */ + c1 = (mclength / cc_width - 1) / 3; + c2 = ecc_level * 3 + (mclength / cc_width - 1) % 3; + c3 = cc_width - 1; + + /* we now encode each row */ + for(i = 0; i <= (mclength / cc_width) - 1; i++) { + for(j = 0; j < cc_width ; j++) { + dummy[j + 1] = chainemc[i * cc_width + j]; + } + k = (i / 3) * 30; + switch(i % 3) { + /* follows this pattern from US Patent 5,243,655: + Row 0: L0 (row #, # of rows) R0 (row #, # of columns) + Row 1: L1 (row #, security level) R1 (row #, # of rows) + Row 2: L2 (row #, # of columns) R2 (row #, security level) + Row 3: L3 (row #, # of rows) R3 (row #, # of columns) + etc. */ + case 0: + dummy[0] = k + c1; + dummy[cc_width + 1] = k + c3; + break; + case 1: + dummy[0] = k + c2; + dummy[cc_width + 1] = k + c1; + break; + case 2: + dummy[0] = k + c3; + dummy[cc_width + 1] = k + c2; + break; + } + strcpy(codebarre, "+*"); /* Start with a start char and a separator */ + + for(j = 0; j <= cc_width + 1; j++) { + switch(i % 3) { + case 1: offset = 929; /* cluster(3) */ break; + case 2: offset = 1858; /* cluster(6) */ break; + default: offset = 0; /* cluster(0) */ break; + } + concat(codebarre, codagemc[offset + dummy[j]]); + concat(codebarre, "*"); + } + concat(codebarre, "-"); + + strcpy(pattern, ""); + for(loop = 0; loop < strlen(codebarre); loop++) { + lookup(BRSET, PDFttf, codebarre[loop], pattern); + } + for(loop = 0; loop < strlen(pattern); loop++) { + if(pattern[loop] == '1') { set_module(symbol, i, loop); } + } + symbol->row_height[i] = 3; + } + symbol->rows = (mclength / cc_width); + symbol->width = strlen(pattern); + + return 0; +} + +int cc_binary_string(struct zint_symbol *symbol, const char source[], char binary_string[], int cc_mode, int *cc_width, int *ecc, int lin_width) +{ /* Handles all data encodation from section 5 of ISO/IEC 24723 */ + int encoding_method, read_posn, d1, d2, value, alpha_pad; + int i, j, mask, ai_crop, ai_crop_posn, fnc1_latch; + long int group_val; + int ai90_mode, latch, remainder, binary_length; + char date_str[4]; +#ifndef _MSC_VER + char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1]; +#else + char* general_field = (char*)_alloca(strlen(source) + 1); + char* general_field_type = (char*)_alloca(strlen(source) + 1); +#endif + int target_bitsize; + + encoding_method = 1; + read_posn = 0; + ai_crop = 0; + ai_crop_posn = -1; + fnc1_latch = 0; + alpha_pad = 0; + ai90_mode = 0; + *ecc = 0; + value = 0; + target_bitsize = 0; + + if((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7')) && (strlen(source) > 8)) { + /* Source starts (10), (11) or (17) */ + encoding_method = 2; + } + + if((source[0] == '9') && (source[1] == '0')) { + /* Source starts (90) */ + encoding_method = 3; + } + + if(encoding_method == 1) { + concat(binary_string, "0"); + } + + if(encoding_method == 2) { + /* Encoding Method field "10" - date and lot number */ + + concat(binary_string, "10"); + + if(source[1] == '0') { + /* No date data */ + concat(binary_string, "11"); + read_posn = 2; + } else { + /* Production Date (11) or Expiration Date (17) */ + date_str[0] = source[2]; + date_str[1] = source[3]; + date_str[2] = '\0'; + group_val = atoi(date_str) * 384; + + date_str[0] = source[4]; + date_str[1] = source[5]; + group_val += (atoi(date_str) - 1) * 32; + + date_str[0] = source[6]; + date_str[1] = source[7]; + group_val += atoi(date_str); + + mask = 0x8000; + for(j = 0; j < 16; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + if(source[1] == '1') { + /* Production Date AI 11 */ + concat(binary_string, "0"); + } else { + /* Expiration Date AI 17 */ + concat(binary_string, "1"); + } + read_posn = 8; + } + + if((source[read_posn] == '1') && (source[read_posn + 1] == '0')) { + /* Followed by AI 10 - strip this from general field */ + read_posn += 2; + } else { + /* An FNC1 character needs to be inserted in the general field */ + fnc1_latch = 1; + } + } + + if (encoding_method == 3) { + /* Encodation Method field of "11" - AI 90 */ +#ifndef _MSC_VER + char ninety[strlen(source) + 1]; +#else + char* ninety = (char*)_alloca(strlen(source) + 1); +#endif + char numeric_part[4]; + int alpha, alphanum, numeric, test1, test2, test3, next_ai_posn; + int numeric_value, table3_letter, mask; + + /* "This encodation method may be used if an element string with an AI + 90 occurs at the start of the data message, and if the data field + following the two-digit AI 90 starts with an alphanumeric string which + complies with a specific format." (para 5.2.2) */ + + i = 0; + do { + ninety[i] = source[i + 2]; + i++; + } while ((strlen(source) > i + 2) && ('[' != source[i + 2])); + ninety[i] = '\0'; + + /* Find out if the AI 90 data is alphabetic or numeric or both */ + + alpha = 0; + alphanum = 0; + numeric = 0; + + for(i = 0; i < strlen(ninety); i++) { + + if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { + /* Character is alphabetic */ + alpha += 1; + } + + if ((ninety[i] >= '0') && (ninety[i] <= '9')) { + /* Character is numeric */ + numeric += 1; + } + + switch(ninety[i]) { + case '*': + case ',': + case '-': + case '.': + case '/': alphanum += 1; break; + } + + if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) { + if((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) { + /* An Invalid AI 90 character */ + strcpy(symbol->errtxt, "Invalid AI 90 data"); + return ERROR_INVALID_DATA; + } + } + } + + /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */ + test1 = -1; + for(i = 3; i >= 0; i--) { + if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { + test1 = i; + } + } + + test2 = 0; + for(i = 0; i < test1; i++) { + if (!((ninety[i] >= '0') && (ninety[i] <= '9'))) { + test2 = 1; + } + } + + /* leading zeros are not permitted */ + test3 = 0; + if((test1 >= 1) && (ninety[0] == '0')) { test3 = 1; } + + if((test1 != -1) && (test2 != 1) && (test3 == 0)) { + /* Encodation method "11" can be used */ + concat(binary_string, "11"); + + numeric -= test1; + alpha --; + + /* Decide on numeric, alpha or alphanumeric mode */ + /* Alpha mode is a special mode for AI 90 */ + + if(alphanum > 0) { + /* Alphanumeric mode */ + concat(binary_string, "0"); + ai90_mode = 1; + } else { + if(alpha > numeric) { + /* Alphabetic mode */ + concat(binary_string, "11"); + ai90_mode = 2; + } else { + /* Numeric mode */ + concat(binary_string, "10"); + ai90_mode = 3; + } + } + + next_ai_posn = 2 + strlen(ninety); + + if(source[next_ai_posn] == '[') { + /* There are more AIs afterwords */ + if((source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) { + /* AI 21 follows */ + ai_crop = 1; + ai_crop_posn = next_ai_posn + 1; + } + + if((source[next_ai_posn + 1] == '8') && (source[next_ai_posn + 2] == '0') && (source[next_ai_posn + 3] == '0') && (source[next_ai_posn + 4] == '4')) { + /* AI 8004 follows */ + ai_crop = 2; + ai_crop_posn = next_ai_posn + 1; + } + } + + switch(ai_crop) { + case 0: concat(binary_string, "0"); break; + case 1: concat(binary_string, "10"); break; + case 2: concat(binary_string, "11"); break; + } + + if(test1 == 0) { + strcpy(numeric_part, "0"); + } else { + for(i = 0; i < test1; i++) { + numeric_part[i] = ninety[i]; + } + numeric_part[i] = '\0'; + } + + numeric_value = atoi(numeric_part); + + table3_letter = -1; + if(numeric_value < 31) { + switch(ninety[test1]) { + case 'B': table3_letter = 0; break; + case 'D': table3_letter = 1; break; + case 'H': table3_letter = 2; break; + case 'I': table3_letter = 3; break; + case 'J': table3_letter = 4; break; + case 'K': table3_letter = 5; break; + case 'L': table3_letter = 6; break; + case 'N': table3_letter = 7; break; + case 'P': table3_letter = 8; break; + case 'Q': table3_letter = 9; break; + case 'R': table3_letter = 10; break; + case 'S': table3_letter = 11; break; + case 'T': table3_letter = 12; break; + case 'V': table3_letter = 13; break; + case 'W': table3_letter = 14; break; + case 'Z': table3_letter = 15; break; + } + } + + if(table3_letter != -1) { + /* Encoding can be done according to 5.2.2 c) 2) */ + /* five bit binary string representing value before letter */ + mask = 0x10; + for(j = 0; j < 5; j++) { + if((numeric_value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + /* followed by four bit representation of letter from Table 3 */ + mask = 0x08; + for(j = 0; j < 4; j++) { + if((table3_letter & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } else { + /* Encoding is done according to 5.2.2 c) 3) */ + concat(binary_string, "11111"); + /* ten bit representation of number */ + mask = 0x200; + for(j = 0; j < 10; j++) { + if((numeric_value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + /* five bit representation of ASCII character */ + mask = 0x10; + for(j = 0; j < 5; j++) { + if(((ninety[test1] - 65) & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + read_posn = test1 + 3; + } else { + /* Use general field encodation instead */ + concat(binary_string, "0"); + read_posn = 0; + } + } + + /* Now encode the rest of the AI 90 data field */ + if(ai90_mode == 2) { + /* Alpha encodation (section 5.2.3) */ + do { + if((source[read_posn] >= '0') && (source[read_posn] <= '9')) { + mask = 0x10; + for(j = 0; j < 5; j++) { + if(((source[read_posn] + 4) & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { + mask = 0x20; + for(j = 0; j < 6; j++) { + if(((source[read_posn] - 65) & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if(source[read_posn] == '[') { + concat(binary_string, "11111"); + } + + read_posn++; + } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); + alpha_pad = 1; /* This is overwritten if a general field is encoded */ + } + + if(ai90_mode == 1) { + /* Alphanumeric mode */ + do { + if((source[read_posn] >= '0') && (source[read_posn] <= '9')) { + mask = 0x10; + for(j = 0; j < 5; j++) { + if(((source[read_posn] - 43) & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { + mask = 0x20; + for(j = 0; j < 6; j++) { + if(((source[read_posn] - 33) & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + switch(source[read_posn]) { + case '[': concat(binary_string, "01111"); break; + case '*': concat(binary_string, "111010"); break; + case ',': concat(binary_string, "111011"); break; + case '-': concat(binary_string, "111100"); break; + case '.': concat(binary_string, "111101"); break; + case '/': concat(binary_string, "111110"); break; + } + + read_posn++; + } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); + } + + read_posn += (2 * ai_crop); + + /* The compressed data field has been processed if appropriate - the + rest of the data (if any) goes into a general-purpose data compaction field */ + + j = 0; + if(fnc1_latch == 1) { + /* Encodation method "10" has been used but it is not followed by + AI 10, so a FNC1 character needs to be added */ + general_field[j] = '['; + j++; + } + + for(i = read_posn; i < strlen(source); i++) { + general_field[j] = source[i]; + j++; + } + general_field[j] = '\0'; + + if(strlen(general_field) != 0) { alpha_pad = 0; } + + latch = 0; + for(i = 0; i < strlen(general_field); i++) { + /* Table 13 - ISO/IEC 646 encodation */ + if((general_field[i] < ' ') || (general_field[i] > 'z')) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } else { + general_field_type[i] = ISOIEC; + } + + if(general_field[i] == '#') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '$') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '@') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == 92) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '^') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == 96) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + + /* Table 12 - Alphanumeric encodation */ + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '*') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == ',') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '-') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '.') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '/') { + general_field_type[i] = ALPHA_OR_ISO; + } + + /* Numeric encodation */ + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + general_field_type[i] = ANY_ENC; + } + if(general_field[i] == '[') { + /* FNC1 can be encoded in any system */ + general_field_type[i] = ANY_ENC; + } + + } + + general_field_type[strlen(general_field)] = '\0'; + + if(latch == 1) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + + for(i = 0; i < strlen(general_field); i++) { + if((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ISOIEC; + } + } + + for(i = 0; i < strlen(general_field); i++) { + if((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ALPHA_OR_ISO; + } + } + + latch = general_rules(general_field, general_field_type); + + i = 0; + do { + switch(general_field_type[i]) { + case NUMERIC: + + if(i != 0) { + if((general_field_type[i - 1] != NUMERIC) && (general_field[i - 1] != '[')) { + concat(binary_string, "000"); /* Numeric latch */ + } + } + + if(general_field[i] != '[') { + d1 = ctoi(general_field[i]); + } else { + d1 = 10; + } + + if(general_field[i + 1] != '[') { + d2 = ctoi(general_field[i + 1]); + } else { + d2 = 10; + } + + value = (11 * d1) + d2 + 8; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + i += 2; + break; + + case ALPHA: + + if(i != 0) { + if((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + } + if(general_field_type[i - 1] == ISOIEC) { + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } + } + + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + + value = general_field[i] - 43; + + mask = 0x10; + for(j = 0; j < 5; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + + value = general_field[i] - 33; + + mask = 0x20; + for(j = 0; j < 6; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if(general_field[i] == '[') concat(binary_string, "01111"); /* FNC1/Numeric latch */ + if(general_field[i] == '*') concat(binary_string, "111010"); /* asterisk */ + if(general_field[i] == ',') concat(binary_string, "111011"); /* comma */ + if(general_field[i] == '-') concat(binary_string, "111100"); /* minus or hyphen */ + if(general_field[i] == '.') concat(binary_string, "111101"); /* period or full stop */ + if(general_field[i] == '/') concat(binary_string, "111110"); /* slash or solidus */ + + i++; + break; + + case ISOIEC: + + if(i != 0) { + if((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } + if(general_field_type[i - 1] == ALPHA) { + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } + } + + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + + value = general_field[i] - 43; + + mask = 0x10; + for(j = 0; j < 5; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + + value = general_field[i] - 1; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'a') && (general_field[i] <= 'z')) { + + value = general_field[i] - 7; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if(general_field[i] == '[') concat(binary_string, "01111"); /* FNC1/Numeric latch */ + if(general_field[i] == '!') concat(binary_string, "11101000"); /* exclamation mark */ + if(general_field[i] == 34) concat(binary_string, "11101001"); /* quotation mark */ + if(general_field[i] == 37) concat(binary_string, "11101010"); /* percent sign */ + if(general_field[i] == '&') concat(binary_string, "11101011"); /* ampersand */ + if(general_field[i] == 39) concat(binary_string, "11101100"); /* apostrophe */ + if(general_field[i] == '(') concat(binary_string, "11101101"); /* left parenthesis */ + if(general_field[i] == ')') concat(binary_string, "11101110"); /* right parenthesis */ + if(general_field[i] == '*') concat(binary_string, "11101111"); /* asterisk */ + if(general_field[i] == '+') concat(binary_string, "11110000"); /* plus sign */ + if(general_field[i] == ',') concat(binary_string, "11110001"); /* comma */ + if(general_field[i] == '-') concat(binary_string, "11110010"); /* minus or hyphen */ + if(general_field[i] == '.') concat(binary_string, "11110011"); /* period or full stop */ + if(general_field[i] == '/') concat(binary_string, "11110100"); /* slash or solidus */ + if(general_field[i] == ':') concat(binary_string, "11110101"); /* colon */ + if(general_field[i] == ';') concat(binary_string, "11110110"); /* semicolon */ + if(general_field[i] == '<') concat(binary_string, "11110111"); /* less-than sign */ + if(general_field[i] == '=') concat(binary_string, "11111000"); /* equals sign */ + if(general_field[i] == '>') concat(binary_string, "11111001"); /* greater-than sign */ + if(general_field[i] == '?') concat(binary_string, "11111010"); /* question mark */ + if(general_field[i] == '_') concat(binary_string, "11111011"); /* underline or low line */ + if(general_field[i] == ' ') concat(binary_string, "11111100"); /* space */ + + i++; + break; + } + } while (i + latch < strlen(general_field)); + + binary_length = strlen(binary_string); + if(cc_mode == 1) { + /* CC-A 2D component - calculate remaining space */ + switch(*(cc_width)) { + case 2: + if(binary_length > 167) { return ERROR_TOO_LONG; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 118) { target_bitsize = 118; } + if(binary_length <= 108) { target_bitsize = 108; } + if(binary_length <= 88) { target_bitsize = 88; } + if(binary_length <= 78) { target_bitsize = 78; } + if(binary_length <= 59) { target_bitsize = 59; } + break; + case 3: + if(binary_length > 167) { return ERROR_TOO_LONG; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 118) { target_bitsize = 118; } + if(binary_length <= 98) { target_bitsize = 98; } + if(binary_length <= 78) { target_bitsize = 78; } + break; + case 4: + if(binary_length > 197) { return ERROR_TOO_LONG; } + if(binary_length <= 197) { target_bitsize = 197; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 108) { target_bitsize = 108; } + if(binary_length <= 78) { target_bitsize = 78; } + break; + } + } + + if(cc_mode == 2) { + /* CC-B 2D component - calculated from ISO/IEC 24728 Table 1 */ + switch(*(cc_width)) { + case 2: + if(binary_length > 336) { return ERROR_TOO_LONG; } + if(binary_length <= 336) { target_bitsize = 336; } + if(binary_length <= 296) { target_bitsize = 296; } + if(binary_length <= 256) { target_bitsize = 256; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 160) { target_bitsize = 160; } + if(binary_length <= 104) { target_bitsize = 104; } + if(binary_length <= 56) { target_bitsize = 56; } + break; + case 3: + if(binary_length > 768) { return ERROR_TOO_LONG; } + if(binary_length <= 768) { target_bitsize = 768; } + if(binary_length <= 648) { target_bitsize = 648; } + if(binary_length <= 536) { target_bitsize = 536; } + if(binary_length <= 416) { target_bitsize = 416; } + if(binary_length <= 304) { target_bitsize = 304; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 152) { target_bitsize = 152; } + if(binary_length <= 112) { target_bitsize = 112; } + if(binary_length <= 72) { target_bitsize = 72; } + if(binary_length <= 32) { target_bitsize = 32; } + break; + case 4: + if(binary_length > 1184) { return ERROR_TOO_LONG; } + if(binary_length <= 1184) { target_bitsize = 1184; } + if(binary_length <= 1016) { target_bitsize = 1016; } + if(binary_length <= 840) { target_bitsize = 840; } + if(binary_length <= 672) { target_bitsize = 672; } + if(binary_length <= 496) { target_bitsize = 496; } + if(binary_length <= 352) { target_bitsize = 352; } + if(binary_length <= 264) { target_bitsize = 264; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 152) { target_bitsize = 152; } + if(binary_length <= 96) { target_bitsize = 96; } + if(binary_length <= 56) { target_bitsize = 56; } + break; + } + } + + if (cc_mode == 3) { + /* CC-C 2D Component is a bit more complex! */ + int byte_length, codewords_used, ecc_level, ecc_codewords, rows; + int codewords_total, target_codewords, target_bytesize; + + byte_length = binary_length / 8; + if(binary_length % 8 != 0) { byte_length++; } + + codewords_used = (byte_length / 6) * 5; + codewords_used += byte_length % 6; + + ecc_level = 7; + if(codewords_used <= 1280) { ecc_level = 6; } + if(codewords_used <= 640) { ecc_level = 5; } + if(codewords_used <= 320) { ecc_level = 4; } + if(codewords_used <= 160) { ecc_level = 3; } + if(codewords_used <= 40) { ecc_level = 2; } + *(ecc) = ecc_level; + ecc_codewords = 1; + for(i = 1; i <= (ecc_level + 1); i++){ + ecc_codewords *= 2; + } + + codewords_used += ecc_codewords; + codewords_used += 3; + + if(codewords_used > symbol->option_3) { + return ERROR_TOO_LONG; + } + /* *(cc_width) = 0.5 + sqrt((codewords_used) / 3); */ + *(cc_width) = (lin_width - 62) / 17; + if((codewords_used / *(cc_width)) > 90) { + /* stop the symbol from becoming too high */ + *(cc_width) = *(cc_width) + 1; + } + + rows = codewords_used / *(cc_width); + if(codewords_used % *(cc_width) != 0) { + rows++; + } + + codewords_total = *(cc_width) * rows; + + target_codewords = codewords_total - ecc_codewords; + target_codewords -= 3; + + target_bytesize = 6 * (target_codewords / 5); + target_bytesize += target_codewords % 5; + + target_bitsize = 8 * target_bytesize; + } + + remainder = binary_length - target_bitsize; + + if(latch == 1) { + i = 0; + /* There is still one more numeric digit to encode */ + + if((remainder >= 4) && (remainder <= 6)) { + d1 = ctoi(general_field[i]); + d1++; + + mask = 0x08; + for(j = 0; j < 4; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } else { + d1 = ctoi(general_field[i]); + d2 = 10; + + value = (11 * d1) + d2 + 8; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + /* This may push the symbol up to the next size */ + } + } + + if(strlen(binary_string) > 11805) { /* (2361 * 5) */ + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* all the code below is repeated from above - it needs to be calculated again because the + size of the symbol may have changed when adding data in the above sequence */ + + binary_length = strlen(binary_string); + if(cc_mode == 1) { + /* CC-A 2D component - calculate padding required */ + switch(*(cc_width)) { + case 2: + if(binary_length > 167) { return ERROR_TOO_LONG; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 118) { target_bitsize = 118; } + if(binary_length <= 108) { target_bitsize = 108; } + if(binary_length <= 88) { target_bitsize = 88; } + if(binary_length <= 78) { target_bitsize = 78; } + if(binary_length <= 59) { target_bitsize = 59; } + break; + case 3: + if(binary_length > 167) { return ERROR_TOO_LONG; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 118) { target_bitsize = 118; } + if(binary_length <= 98) { target_bitsize = 98; } + if(binary_length <= 78) { target_bitsize = 78; } + break; + case 4: + if(binary_length > 197) { return ERROR_TOO_LONG; } + if(binary_length <= 197) { target_bitsize = 197; } + if(binary_length <= 167) { target_bitsize = 167; } + if(binary_length <= 138) { target_bitsize = 138; } + if(binary_length <= 108) { target_bitsize = 108; } + if(binary_length <= 78) { target_bitsize = 78; } + break; + } + } + + if(cc_mode == 2) { + /* CC-B 2D component */ + switch(*(cc_width)) { + case 2: + if(binary_length > 336) { return ERROR_TOO_LONG; } + if(binary_length <= 336) { target_bitsize = 336; } + if(binary_length <= 296) { target_bitsize = 296; } + if(binary_length <= 256) { target_bitsize = 256; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 160) { target_bitsize = 160; } + if(binary_length <= 104) { target_bitsize = 104; } + if(binary_length <= 56) { target_bitsize = 56; } + break; + case 3: + if(binary_length > 768) { return ERROR_TOO_LONG; } + if(binary_length <= 768) { target_bitsize = 768; } + if(binary_length <= 648) { target_bitsize = 648; } + if(binary_length <= 536) { target_bitsize = 536; } + if(binary_length <= 416) { target_bitsize = 416; } + if(binary_length <= 304) { target_bitsize = 304; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 152) { target_bitsize = 152; } + if(binary_length <= 112) { target_bitsize = 112; } + if(binary_length <= 72) { target_bitsize = 72; } + if(binary_length <= 32) { target_bitsize = 32; } + break; + case 4: + if(binary_length > 1184) { return ERROR_TOO_LONG; } + if(binary_length <= 1184) { target_bitsize = 1184; } + if(binary_length <= 1016) { target_bitsize = 1016; } + if(binary_length <= 840) { target_bitsize = 840; } + if(binary_length <= 672) { target_bitsize = 672; } + if(binary_length <= 496) { target_bitsize = 496; } + if(binary_length <= 352) { target_bitsize = 352; } + if(binary_length <= 264) { target_bitsize = 264; } + if(binary_length <= 208) { target_bitsize = 208; } + if(binary_length <= 152) { target_bitsize = 152; } + if(binary_length <= 96) { target_bitsize = 96; } + if(binary_length <= 56) { target_bitsize = 56; } + break; + } + } + + if (cc_mode == 3) { + /* CC-C 2D Component is a bit more complex! */ + int byte_length, codewords_used, ecc_level, ecc_codewords, rows; + int codewords_total, target_codewords, target_bytesize; + + byte_length = binary_length / 8; + if(binary_length % 8 != 0) { byte_length++; } + + codewords_used = (byte_length / 6) * 5; + codewords_used += byte_length % 6; + + ecc_level = 7; + if(codewords_used <= 1280) { ecc_level = 6; } + if(codewords_used <= 640) { ecc_level = 5; } + if(codewords_used <= 320) { ecc_level = 4; } + if(codewords_used <= 160) { ecc_level = 3; } + if(codewords_used <= 40) { ecc_level = 2; } + *(ecc) = ecc_level; + ecc_codewords = 1; + for(i = 1; i <= (ecc_level + 1); i++){ + ecc_codewords *= 2; + } + + codewords_used += ecc_codewords; + codewords_used += 3; + + if(codewords_used > symbol->option_3) { + return ERROR_TOO_LONG; + } + /* *(cc_width) = 0.5 + sqrt((codewords_used) / 3); */ + *(cc_width) = (lin_width - 62) / 17; + if((codewords_used / *(cc_width)) > 90) { + /* stop the symbol from becoming too high */ + *(cc_width) = *(cc_width) + 1; + } + + rows = codewords_used / *(cc_width); + if(codewords_used % *(cc_width) != 0) { + rows++; + } + + codewords_total = *(cc_width) * rows; + + target_codewords = codewords_total - ecc_codewords; + target_codewords -= 3; + + target_bytesize = 6 * (target_codewords / 5); + target_bytesize += target_codewords % 5; + + target_bitsize = 8 * target_bytesize; + } + + if(binary_length < target_bitsize) { + /* Now add padding to binary string */ + if (alpha_pad == 1) { + concat(binary_string, "11111"); + alpha_pad = 0; + /* Extra FNC1 character required after Alpha encodation (section 5.2.3) */ + } + + if ((strlen(general_field) != 0) && (general_field_type[strlen(general_field) - 1] == NUMERIC)) { + concat(binary_string, "0000"); + } + + while (strlen(binary_string) < target_bitsize) { + concat(binary_string, "00100"); + } + + if(strlen(binary_string) > target_bitsize) { + binary_string[target_bitsize] = '\0'; + } + } + + return 0; +} + +void add_leading_zeroes(struct zint_symbol *symbol) +{ + int with_addon = 0; + int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h, n = 0; + + h = strlen(symbol->primary); + for(i = 0; i < h; i++) { + if(symbol->primary[i] == '+') { + with_addon = 1; + } else { + if(with_addon == 0) { + first_len++; + } else { + second_len++; + } + } + } + + /* Calculate target lengths */ + if(first_len <= 12) { zfirst_len = 12; } + if(first_len <= 7) { zfirst_len = 7; } + if(second_len <= 5) { zsecond_len = 5; } + if(second_len <= 2) { zsecond_len = 2; } + if(second_len == 0) { zsecond_len = 0; } + + /* Add leading zeroes */ + n = zfirst_len - first_len; + if (n > 0) + { + memmove(symbol->primary + n, symbol->primary, h); + memset(symbol->primary, '0', n); + } + n += first_len + 1; + if (zsecond_len) + { + memmove(symbol->primary + n + zsecond_len, symbol->primary + n, second_len); + memset(symbol->primary + n , '0', zsecond_len); + n += zsecond_len + second_len; + } + symbol->primary[n] = '\0'; +} + +int composite(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int error_number, cc_mode, cc_width, ecc_level; + int j, i, k, separator_row; + unsigned int rs = length + 1; + unsigned int bs = 20 * rs; + unsigned int pri_len; +#ifndef _MSC_VER + char reduced[rs]; + char binary_string[bs]; +#else + char* reduced = (char*)_alloca(rs); + char* binary_string = (char*)_alloca(bs); +#endif + struct zint_symbol *linear; + int top_shift, bottom_shift; + + error_number = 0; + separator_row = 0; + pri_len = strlen(symbol->primary); + if(pri_len == 0) { + strcpy(symbol->errtxt, "No primary (linear) message in 2D composite"); + return ERROR_INVALID_OPTION; + } + + if(length > 2990) { + strcpy(symbol->errtxt, "2D component input data too long"); + return ERROR_TOO_LONG; + } + + linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */ + + error_number = gs1_verify(symbol, source, length, reduced); + if(error_number != 0) { return error_number; } + + cc_mode = symbol->option_1; + + if((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) { + /* CC-C can only be used with a GS1-128 linear part */ + strcpy(symbol->errtxt, "Invalid mode (CC-C only valid with GS1-128 linear component)"); + return ERROR_INVALID_OPTION; + } + + linear->symbology = symbol->symbology; + + if(linear->symbology != BARCODE_EAN128_CC) { + /* Set the "component linkage" flag in the linear component */ + linear->option_1 = 2; + } else { + /* GS1-128 needs to know which type of 2D component is used */ + linear->option_1 = cc_mode; + } + + switch(symbol->symbology) { + case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; + case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *)symbol->primary, pri_len); break; + } + + if(error_number != 0) { + strcpy(symbol->errtxt, linear->errtxt); + concat(symbol->errtxt, " in linear component"); + return error_number; + } + + switch(symbol->symbology) { + /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */ + case BARCODE_EANX_CC: + switch(pri_len) { + case 7: /* EAN-8 */ + case 10: /* EAN-8 + 2 */ + case 13: /* EAN-8 + 5 */ + cc_width = 3; + break; + case 12: /* EAN-13 */ + case 15: /* EAN-13 + 2 */ + case 18: /* EAN-13 + 5 */ + cc_width = 4; + break; + } + break; + case BARCODE_EAN128_CC: cc_width = 4; break; + case BARCODE_RSS14_CC: cc_width = 4; break; + case BARCODE_RSS_LTD_CC: cc_width = 3; break; + case BARCODE_RSS_EXP_CC: cc_width = 4; break; + case BARCODE_UPCA_CC: cc_width = 4; break; + case BARCODE_UPCE_CC: cc_width = 2; break; + case BARCODE_RSS14STACK_CC: cc_width = 2; break; + case BARCODE_RSS14_OMNI_CC: cc_width = 2; break; + case BARCODE_RSS_EXPSTACK_CC: cc_width = 4; break; + } + + memset(binary_string, 0, bs); + + if(cc_mode < 1 || cc_mode > 3) { cc_mode = 1; } + + if(cc_mode == 1) { + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); + if (i == ERROR_TOO_LONG) { + cc_mode = 2; + } + } + + if(cc_mode == 2) { /* If the data didn't fit into CC-A it is recalculated for CC-B */ + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); + if (i == ERROR_TOO_LONG) { + if(symbol->symbology != BARCODE_EAN128_CC) { + return ERROR_TOO_LONG; + } else { + cc_mode = 3; + } + } + } + + if(cc_mode == 3) { /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated + for CC-C */ + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); + if (i == ERROR_TOO_LONG) { + return ERROR_TOO_LONG; + } + } + + switch(cc_mode) { /* Note that ecc_level is only relevant to CC-C */ + case 1: error_number = cc_a(symbol, binary_string, cc_width); break; + case 2: error_number = cc_b(symbol, binary_string, cc_width); break; + case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level); break; + } + + if(error_number != 0) { + return ERROR_ENCODING_PROBLEM; + } + + /* Merge the linear component with the 2D component */ + + top_shift = 0; + bottom_shift = 0; + + switch(symbol->symbology) { + /* Determine horizontal alignment (according to section 12.3) */ + case BARCODE_EANX_CC: + switch(pri_len) { + case 7: /* EAN-8 */ + case 10: /* EAN-8 + 2 */ + case 13: /* EAN-8 + 5 */ + bottom_shift = 13; + break; + case 12: /* EAN-13 */ + case 15: /* EAN-13 + 2 */ + case 18: /* EAN-13 + 5 */ + bottom_shift = 2; + break; + } + break; + case BARCODE_EAN128_CC: if(cc_mode == 3) { + bottom_shift = 7; + } + break; + case BARCODE_RSS14_CC: bottom_shift = 4; break; + case BARCODE_RSS_LTD_CC: bottom_shift = 9; break; + case BARCODE_RSS_EXP_CC: k = 1; + while((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { + /* while((linear->encoded_data[1][k - 1] != '1') && (linear->encoded_data[1][k] != '0')) { */ + k++; + } + top_shift = k; + break; + case BARCODE_UPCA_CC: bottom_shift = 2; break; + case BARCODE_UPCE_CC: bottom_shift = 2; break; + case BARCODE_RSS14STACK_CC: top_shift = 1; break; + case BARCODE_RSS14_OMNI_CC: top_shift = 1; break; + case BARCODE_RSS_EXPSTACK_CC: k = 1; + while((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { + /* while((linear->encoded_data[1][k - 1] != '1') && (linear->encoded_data[1][k] != '0')) { */ + k++; + } + top_shift = k; + break; + } + + if(top_shift != 0) { + /* Move the 2d component of the symbol horizontally */ + for(i = 0; i <= symbol->rows; i++) { + for(j = (symbol->width + top_shift); j >= top_shift; j--) { + if(module_is_set(symbol, i, j - top_shift)) { set_module(symbol, i, j); } else { unset_module(symbol, i, j); } + } + for(j = 0; j < top_shift; j++) { + unset_module(symbol, i, j); + } + } + } + + /* Merge linear and 2D components into one structure */ + for(i = 0; i <= linear->rows; i++) { + symbol->row_height[symbol->rows + i] = linear->row_height[i]; + for(j = 0; j <= linear->width; j++) { + if(module_is_set(linear, i, j)) { set_module(symbol, i + symbol->rows, j + bottom_shift); } else { unset_module(symbol, i + symbol->rows, j + bottom_shift); } + } + } + if((linear->width + bottom_shift) > symbol->width) { + symbol->width = linear->width + bottom_shift; + } + if((symbol->width + top_shift) > symbol->width) { + symbol->width += top_shift; + } + symbol->rows += linear->rows; + ustrcpy(symbol->text, (unsigned char *)linear->text); + + ZBarcode_Delete(linear); + + return error_number; +} diff --git a/backend/composite.h b/backend/composite.h new file mode 100644 index 00000000..ac5f268e --- /dev/null +++ b/backend/composite.h @@ -0,0 +1,62 @@ +/* composite.c - Tables for UCC.EAN Composite Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +#define NUMERIC 110 +#define ALPHA 97 +#define ISOIEC 105 +#define INVALID_CHAR 100 +#define ANY_ENC 120 +#define ALPHA_OR_ISO 121 + +/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */ +static int ccaCoeffs[30] = { + /* k = 4 */ + 522, 568, 723, 809, + + /* k = 5 */ + 427, 919, 460, 155, 566, + + /* k = 6 */ + 861, 285, 19, 803, 17, 766, + + /* k = 7 */ + 76, 925, 537, 597, 784, 691, 437, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379 +}; + +/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */ +static int ccaVariants[51] = { + 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, + 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, + 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22 +}; + +/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */ +static int aRAPTable[68] = { + 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, + 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 2, 14, 9, + 19, 33, 12, 40, 4, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41, + 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 +}; + +/* Row Address Patterns are as defined in pdf417.h */ diff --git a/backend/dllversion.c b/backend/dllversion.c new file mode 100644 index 00000000..05008631 --- /dev/null +++ b/backend/dllversion.c @@ -0,0 +1,31 @@ +/* Sed: http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/versions.asp */ +#if defined (_WIN32) && (defined(_USRDLL) || defined(DLL_EXPORT) || defined(PIC)) +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +__declspec(dllexport) HRESULT DllGetVersion (DLLVERSIONINFO2* pdvi); + +#ifdef __cplusplus +} +#endif + +HRESULT DllGetVersion (DLLVERSIONINFO2* pdvi) +{ + if (!pdvi || (sizeof(*pdvi) != pdvi->info1.cbSize)) + return (E_INVALIDARG); + + pdvi->info1.dwMajorVersion = 2; + pdvi->info1.dwMinorVersion = 2; + pdvi->info1.dwBuildNumber = 1; + pdvi->info1.dwPlatformID = DLLVER_PLATFORM_WINDOWS; + if (sizeof(DLLVERSIONINFO2) == pdvi->info1.cbSize) + pdvi->ullVersion = MAKEDLLVERULL(2, 2, 1, 0); + + return S_OK; +} +#endif /* _WIN32 */ diff --git a/backend/dm200.c b/backend/dm200.c new file mode 100644 index 00000000..f23b4ebd --- /dev/null +++ b/backend/dm200.c @@ -0,0 +1,881 @@ +/* dm200.c Handles Data Matrix ECC 200 symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + developed from and including some functions from: + IEC16022 bar code generation + Adrian Kennard, Andrews & Arnold Ltd + with help from Cliff Hones on the RS coding + + (c) 2004 Adrian Kennard, Andrews & Arnold Ltd + (c) 2006 Stefan Schmidt + + 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 +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "reedsol.h" +#include "common.h" +#include "dm200.h" + +// Annex M placement alorithm low level +static void ecc200placementbit(int *array, int NR, int NC, int r, int c, int p, char b) +{ + if (r < 0) { + r += NR; + c += 4 - ((NR + 4) % 8); + } + if (c < 0) { + c += NC; + r += 4 - ((NC + 4) % 8); + } + array[r * NC + c] = (p << 3) + b; +} + +static void ecc200placementblock(int *array, int NR, int NC, int r, + int c, int p) +{ + ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7); + ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6); + ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5); + ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4); + ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3); + ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2); + ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1); + ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0); +} + +static void ecc200placementcornerA(int *array, int NR, int NC, int p) +{ + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); + ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); +} + +static void ecc200placementcornerB(int *array, int NR, int NC, int p) +{ + ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); +} + +static void ecc200placementcornerC(int *array, int NR, int NC, int p) +{ + ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); + ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); +} + +static void ecc200placementcornerD(int *array, int NR, int NC, int p) +{ + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6); + ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2); + ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); +} + +// Annex M placement alorithm main function +static void ecc200placement(int *array, int NR, int NC) +{ + int r, c, p; + // invalidate + for (r = 0; r < NR; r++) + for (c = 0; c < NC; c++) + array[r * NC + c] = 0; + // start + p = 1; + r = 4; + c = 0; + do { + // check corner + if (r == NR && !c) + ecc200placementcornerA(array, NR, NC, p++); + if (r == NR - 2 && !c && NC % 4) + ecc200placementcornerB(array, NR, NC, p++); + if (r == NR - 2 && !c && (NC % 8) == 4) + ecc200placementcornerC(array, NR, NC, p++); + if (r == NR + 4 && c == 2 && !(NC % 8)) + ecc200placementcornerD(array, NR, NC, p++); + // up/right + do { + if (r < NR && c >= 0 && !array[r * NC + c]) + ecc200placementblock(array, NR, NC, r, c, p++); + r -= 2; + c += 2; + } + while (r >= 0 && c < NC); + r++; + c += 3; + // down/left + do { + if (r >= 0 && c < NC && !array[r * NC + c]) + ecc200placementblock(array, NR, NC, r, c, p++); + r += 2; + c -= 2; + } + while (r < NR && c >= 0); + r += 3; + c++; + } + while (r < NR || c < NC); + // unfilled corner + if (!array[NR * NC - 1]) + array[NR * NC - 1] = array[NR * NC - NC - 2] = 1; +} + +// calculate and append ecc code, and if necessary interleave +static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock) +{ + int blocks = (bytes + 2) / datablock, b; + rs_init_gf(0x12d); + rs_init_code(rsblock, 1); + for (b = 0; b < blocks; b++) { + unsigned char buf[256], ecc[256]; + int n, p = 0; + for (n = b; n < bytes; n += blocks) + buf[p++] = binary[n]; + rs_encode(p, buf, ecc); + p = rsblock - 1; // comes back reversed + for (n = b; n < rsblock * blocks; n += blocks) + binary[bytes + n] = ecc[p--]; + } + rs_free(); +} + +int isx12(unsigned char source) +{ + if(source == 13) { return 1; } + if(source == 42) { return 1; } + if(source == 62) { return 1; } + if(source == 32) { return 1; } + if((source >= '0') && (source <= '9')) { return 1; } + if((source >= 'A') && (source <= 'Z')) { return 1; } + + return 0; +} + +void dminsert(char binary_string[], int posn, char newbit) +{ /* Insert a character into the middle of a string at position posn */ + int i, end; + + end = strlen(binary_string); + for(i = end; i > posn; i--) { + binary_string[i] = binary_string[i - 1]; + } + binary_string[posn] = newbit; +} + +void insert_value(unsigned char binary_stream[], int posn, int streamlen, char newbit) +{ + int i; + + for(i = streamlen; i > posn; i--) { + binary_stream[i] = binary_stream[i - 1]; + } + binary_stream[posn] = newbit; +} + +int look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) +{ + /* A custom version of the 'look ahead test' from Annex P */ + /* This version is deliberately very reluctant to end a data stream with EDIFACT encoding */ + + float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count; + int sp, done, best_scheme; + char reduced_char; + + /* step (j) */ + if(current_mode == DM_ASCII) { + ascii_count = 0.0; + c40_count = 1.0; + text_count = 1.0; + x12_count = 1.0; + edf_count = 1.0; + b256_count = 1.25; + } else { + ascii_count = 1.0; + c40_count = 2.0; + text_count = 2.0; + x12_count = 2.0; + edf_count = 2.0; + b256_count = 2.25; + } + + switch(current_mode) { + case DM_C40: c40_count = 0.0; break; + case DM_TEXT: text_count = 0.0; break; + case DM_X12: x12_count = 0.0; break; + case DM_EDIFACT: edf_count = 0.0; break; + case DM_BASE256: b256_count = 0.0; break; + } + + for(sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { + + if(source[sp] <= 127) { reduced_char = source[sp]; } else { reduced_char = source[sp] - 127; } + + if((source[sp] >= '0') && (source[sp] <= '9')) { ascii_count += 0.5; } else { ascii_count += 1.0; } + if(source[sp] > 127) { ascii_count += 1.0; } + + done = 0; + if(reduced_char == ' ') { c40_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= '0') && (reduced_char <= '9')) { c40_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= 'A') && (reduced_char <= 'Z')) { c40_count += (2.0 / 3.0); done = 1; } + if(source[sp] > 127) { c40_count += (4.0 / 3.0); } + if(done == 0) { c40_count += (4.0 / 3.0); } + + done = 0; + if(reduced_char == ' ') { text_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= '0') && (reduced_char <= '9')) { text_count += (2.0 / 3.0); done = 1; } + if((reduced_char >= 'a') && (reduced_char <= 'z')) { text_count += (2.0 / 3.0); done = 1; } + if(source[sp] > 127) { text_count += (4.0 / 3.0); } + if(done == 0) { text_count += (4.0 / 3.0); } + + if(isx12(source[sp])) { x12_count += (2.0 / 3.0); } else { x12_count += 4.0; } + + /* step (p) */ + done = 0; + if((source[sp] >= ' ') && (source[sp] <= '^')) { edf_count += (3.0 / 4.0); } else { edf_count += 6.0; } + if(gs1 && (source[sp] == '[')) { edf_count += 6.0; } + if(sp >= (sourcelen - 5)) { edf_count += 6.0; } /* MMmmm fudge! */ + + /* step (q) */ + if(gs1 && (source[sp] == '[')) { b256_count += 4.0; } else { b256_count += 1.0; } + + /* printf("%c lat a%.2f c%.2f t%.2f x%.2f e%.2f b%.2f\n", source[sp], ascii_count, c40_count, text_count, x12_count, edf_count, b256_count); */ + + } + + best_count = ascii_count; + best_scheme = DM_ASCII; + + if(b256_count <= best_count) { + best_count = b256_count; + best_scheme = DM_BASE256; + } + + if(edf_count <= best_count) { + best_count = edf_count; + best_scheme = DM_EDIFACT; + } + + if(text_count <= best_count) { + best_count = text_count; + best_scheme = DM_TEXT; + } + + if(x12_count <= best_count) { + best_count = x12_count; + best_scheme = DM_X12; + } + + if(c40_count <= best_count) { + best_count = c40_count; + best_scheme = DM_C40; + } + + return best_scheme; +} + +int dm200encode(struct zint_symbol *symbol, unsigned char source[], unsigned char target[], int *last_mode, int length) +{ + /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate */ + /* Supports encoding FNC1 in supporting systems */ + + int sp, tp, i, gs1; + int current_mode, next_mode; + int inputlen = length; + int c40_buffer[6], c40_p; + int text_buffer[6], text_p; + int x12_buffer[6], x12_p; + int edifact_buffer[8], edifact_p; + int debug = 0; +#ifndef _MSC_VER + char binary[2 * inputlen]; +#else + char* binary = (char*)_alloca(2 * inputlen); +#endif + + sp = 0; + tp = 0; + memset(c40_buffer, 0, 6); + c40_p = 0; + memset(text_buffer, 0, 6); + text_p = 0; + memset(x12_buffer, 0, 6); + x12_p = 0; + memset(edifact_buffer, 0, 8); + edifact_p = 0; + strcpy(binary, ""); + + /* step (a) */ + current_mode = DM_ASCII; + next_mode = DM_ASCII; + + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + + if(gs1) { + target[tp] = 232; tp++; + concat(binary, " "); + if(debug) printf("FN1 "); + } /* FNC1 */ + + if(symbol->output_options & READER_INIT) { + if(gs1) { + strcpy(symbol->errtxt, "Cannot encode in GS1 mode and Reader Initialisation at the same time"); + return ERROR_INVALID_OPTION; + } else { + target[tp] = 234; tp++; /* Reader Programming */ + concat(binary, " "); + if(debug) printf("RP "); + } + } + + while (sp < inputlen) { + + current_mode = next_mode; + + /* step (b) - ASCII encodation */ + if(current_mode == DM_ASCII) { + next_mode = DM_ASCII; + + if(istwodigits(source, sp) && ((sp + 1) != inputlen)) { + target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; + if(debug) printf("N%d ", target[tp] - 130); + tp++; concat(binary, " "); + sp += 2; + } else { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + + if(next_mode != DM_ASCII) { + switch(next_mode) { + case DM_C40: target[tp] = 230; tp++; concat(binary, " "); + if(debug) printf("C40 "); break; + case DM_TEXT: target[tp] = 239; tp++; concat(binary, " "); + if(debug) printf("TEX "); break; + case DM_X12: target[tp] = 238; tp++; concat(binary, " "); + if(debug) printf("X12 "); break; + case DM_EDIFACT: target[tp] = 240; tp++; concat(binary, " "); + if(debug) printf("EDI "); break; + case DM_BASE256: target[tp] = 231; tp++; concat(binary, " "); + if(debug) printf("BAS "); break; + } + } else { + if(source[sp] > 127) { + target[tp] = 235; /* FNC4 */ + if(debug) printf("FN4 "); + tp++; + target[tp] = (source[sp] - 128) + 1; + if(debug) printf("A%02X ", target[tp] - 1); + tp++; concat(binary, " "); + } else { + if(gs1 && (source[sp] == '[')) { + target[tp] = 232; /* FNC1 */ + if(debug) printf("FN1 "); + } else { + target[tp] = source[sp] + 1; + if(debug) printf("A%02X ", target[tp] - 1); + } + tp++; + concat(binary, " "); + } + sp++; + } + } + + } + + /* step (c) C40 encodation */ + if(current_mode == DM_C40) { + int shift_set, value; + + next_mode = DM_C40; + if(c40_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if(next_mode != DM_C40) { + target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if(source[sp] > 127) { + c40_buffer[c40_p] = 1; c40_p++; + c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */ + shift_set = c40_shift[source[sp] - 128]; + value = c40_value[source[sp] - 128]; + } else { + shift_set = c40_shift[source[sp]]; + value = c40_value[source[sp]]; + } + + if(gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if(shift_set != 0) { + c40_buffer[c40_p] = shift_set - 1; c40_p++; + } + c40_buffer[c40_p] = value; c40_p++; + + if(c40_p >= 3) { + int iv; + + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + concat(binary, " "); + if (debug) printf("[%d %d %d] ", c40_buffer[0], c40_buffer[1], c40_buffer[2]); + + c40_buffer[0] = c40_buffer[3]; + c40_buffer[1] = c40_buffer[4]; + c40_buffer[2] = c40_buffer[5]; + c40_buffer[3] = 0; + c40_buffer[4] = 0; + c40_buffer[5] = 0; + c40_p -= 3; + } + sp++; + } + } + + /* step (d) Text encodation */ + if(current_mode == DM_TEXT) { + int shift_set, value; + + next_mode = DM_TEXT; + if(text_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if(next_mode != DM_TEXT) { + target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if(source[sp] > 127) { + text_buffer[text_p] = 1; text_p++; + text_buffer[text_p] = 30; text_p++; /* Upper Shift */ + shift_set = text_shift[source[sp] - 128]; + value = text_value[source[sp] - 128]; + } else { + shift_set = text_shift[source[sp]]; + value = text_value[source[sp]]; + } + + if(gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if(shift_set != 0) { + text_buffer[text_p] = shift_set - 1; text_p++; + } + text_buffer[text_p] = value; text_p++; + + if(text_p >= 3) { + int iv; + + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + concat(binary, " "); + if (debug) printf("[%d %d %d] ", text_buffer[0], text_buffer[1], text_buffer[2]); + + text_buffer[0] = text_buffer[3]; + text_buffer[1] = text_buffer[4]; + text_buffer[2] = text_buffer[5]; + text_buffer[3] = 0; + text_buffer[4] = 0; + text_buffer[5] = 0; + text_p -= 3; + } + sp++; + } + } + + /* step (e) X12 encodation */ + if(current_mode == DM_X12) { + int value = 0; + + next_mode = DM_X12; + if(text_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if(next_mode != DM_X12) { + target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if(source[sp] == 13) { value = 0; } + if(source[sp] == '*') { value = 1; } + if(source[sp] == '>') { value = 2; } + if(source[sp] == ' ') { value = 3; } + if((source[sp] >= '0') && (source[sp] <= '9')) { value = (source[sp] - '0') + 4; } + if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = (source[sp] - 'A') + 14; } + + x12_buffer[x12_p] = value; x12_p++; + + if(x12_p >= 3) { + int iv; + + iv = (1600 * x12_buffer[0]) + (40 * x12_buffer[1]) + (x12_buffer[2]) + 1; + target[tp] = iv / 256; tp++; + target[tp] = iv % 256; tp++; + concat(binary, " "); + if (debug) printf("[%d %d %d] ", x12_buffer[0], x12_buffer[1], x12_buffer[2]); + + x12_buffer[0] = x12_buffer[3]; + x12_buffer[1] = x12_buffer[4]; + x12_buffer[2] = x12_buffer[5]; + x12_buffer[3] = 0; + x12_buffer[4] = 0; + x12_buffer[5] = 0; + x12_p -= 3; + } + sp++; + } + } + + /* step (f) EDIFACT encodation */ + if(current_mode == DM_EDIFACT) { + int value = 0; + + next_mode = DM_EDIFACT; + if(edifact_p == 3) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if(next_mode != DM_EDIFACT) { + edifact_buffer[edifact_p] = 31; edifact_p++; + next_mode = DM_ASCII; + } else { + if((source[sp] >= '@') && (source[sp] <= '^')) { value = source[sp] - '@'; } + if((source[sp] >= ' ') && (source[sp] <= '?')) { value = source[sp]; } + + edifact_buffer[edifact_p] = value; edifact_p++; + sp++; + } + + if(edifact_p >= 4) { + target[tp] = (edifact_buffer[0] << 2) + ((edifact_buffer[1] & 0x30) >> 4); tp++; + target[tp] = ((edifact_buffer[1] & 0x0f) << 4) + ((edifact_buffer[2] & 0x3c) >> 2); tp++; + target[tp] = ((edifact_buffer[2] & 0x03) << 6) + edifact_buffer[3]; tp++; + concat(binary, " "); + if (debug) printf("[%d %d %d %d] ", edifact_buffer[0], edifact_buffer[1], edifact_buffer[2], edifact_buffer[3]); + + edifact_buffer[0] = edifact_buffer[4]; + edifact_buffer[1] = edifact_buffer[5]; + edifact_buffer[2] = edifact_buffer[6]; + edifact_buffer[3] = edifact_buffer[7]; + edifact_buffer[4] = 0; + edifact_buffer[5] = 0; + edifact_buffer[6] = 0; + edifact_buffer[7] = 0; + edifact_p -= 4; + } + } + + /* step (g) Base 256 encodation */ + if(current_mode == DM_BASE256) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + + if(next_mode == DM_BASE256) { + target[tp] = source[sp]; + if(debug) printf("B%02X ", target[tp]); + tp++; + sp++; + concat(binary, "b"); + } else { + next_mode = DM_ASCII; + if(debug) printf("ASC "); + } + } + + if(tp > 1558) { + return 0; + } + + } /* while */ + + /* Empty buffers */ + if(c40_p == 2) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 2] + 1; tp++; + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); + current_mode = DM_ASCII; + } + if(c40_p == 1) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X ", target[tp - 1] - 1); + current_mode = DM_ASCII; + } + + if(text_p == 2) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 2] + 1; tp++; + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); + current_mode = DM_ASCII; + } + if(text_p == 1) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X ", target[tp - 1] - 1); + current_mode = DM_ASCII; + } + + if(x12_p == 2) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 2] + 1; tp++; + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); + current_mode = DM_ASCII; + } + if(x12_p == 1) { + target[tp] = 254; tp++; /* unlatch */ + target[tp] = source[inputlen - 1] + 1; tp++; + concat(binary, " "); + if(debug) printf("ASC A%02X ", target[tp - 1] - 1); + current_mode = DM_ASCII; + } + + /* Add length and randomising algorithm to b256 */ + i = 0; + while (i < tp) { + if(binary[i] == 'b') { + if((i == 0) || ((i != 0) && (binary[i - 1] != 'b'))) { + /* start of binary data */ + int binary_count; /* length of b256 data */ + + for(binary_count = 0; binary[binary_count + i] == 'b'; binary_count++); + + if(binary_count <= 249) { + dminsert(binary, i, 'b'); + insert_value(target, i, tp, binary_count); tp++; + } else { + dminsert(binary, i, 'b'); + dminsert(binary, i + 1, 'b'); + insert_value(target, i, tp, (binary_count / 250) + 249); tp++; + insert_value(target, i + 1, tp, binary_count % 250); tp++; + } + } + } + i++; + } + + for(i = 0; i < tp; i++) { + if(binary[i] == 'b') { + int prn, temp; + + prn = ((149 * (i + 1)) % 255) + 1; + temp = target[i] + prn; + if (temp <= 255) { target[i] = temp; } else { target[i] = temp - 256; } + } + } + + if(debug) { + printf("\n\n"); + for(i = 0; i < tp; i++){ + printf("%02X ", target[i]); + } + printf("\n"); + } + + *(last_mode) = current_mode; + return tp; +} + +void add_tail(unsigned char target[], int tp, int tail_length, int last_mode) +{ + /* adds unlatch and pad bits */ + int i, prn, temp; + + switch(last_mode) { + case DM_C40: + case DM_TEXT: + case DM_X12: + target[tp] = 254; tp++; /* Unlatch */ + tail_length--; + } + + for(i = tail_length; i > 0; i--) { + if(i == tail_length) { + target[tp] = 129; tp++; /* Pad */ + } else { + prn = ((149 * (tp + 1)) % 253) + 1; + temp = 129 + prn; + if(temp <= 254) { + target[tp] = temp; tp++; + } else { + target[tp] = temp - 254; tp++; + } + } + } +} + +int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int inputlen, i; + unsigned char binary[2000]; + int binlen; + int symbolsize, optionsize, calcsize; + int taillength, error_number = 0; + int H, W, FH, FW, datablock, bytes, rsblock; + int last_mode; + unsigned char *grid = 0; + inputlen = length; + + binlen = dm200encode(symbol, source, binary, &last_mode, length); + + if(binlen == 0) { + strcpy(symbol->errtxt, "Data too long to fit in symbol"); + return ERROR_TOO_LONG; + } + + if((symbol->option_2 >= 1) && (symbol->option_2 <= 30)) { + optionsize = intsymbol[symbol->option_2 - 1]; + } else { + optionsize = -1; + } + + calcsize = 29; + for(i = 29; i > -1; i--) { + if(matrixbytes[i] > binlen) { + calcsize = i; + } + } + + if(symbol->option_3 == DM_SQUARE) { + /* Force to use square symbol */ + switch(calcsize) { + case 2: + case 4: + case 6: + case 9: + case 11: + case 14: + calcsize++; + } + } + + symbolsize = optionsize; + if(calcsize > optionsize) { + symbolsize = calcsize; + if(optionsize != -1) { + /* flag an error */ + error_number = WARN_INVALID_OPTION; + strcpy(symbol->errtxt, "Data does not fit in selected symbol size"); + } + } + + H = matrixH[symbolsize]; + W = matrixW[symbolsize]; + FH = matrixFH[symbolsize]; + FW = matrixFW[symbolsize]; + bytes = matrixbytes[symbolsize]; + datablock = matrixdatablock[symbolsize]; + rsblock = matrixrsblock[symbolsize]; + + taillength = bytes - binlen; + + if(taillength != 0) { + add_tail(binary, binlen, taillength, last_mode); + } + + // ecc code + ecc200(binary, bytes, datablock, rsblock); + { // placement + int x, y, NC, NR, *places; + NC = W - 2 * (W / FW); + NR = H - 2 * (H / FH); + places = (int*)malloc(NC * NR * sizeof(int)); + ecc200placement(places, NR, NC); + grid = (unsigned char*)malloc(W * H); + memset(grid, 0, W * H); + for (y = 0; y < H; y += FH) { + for (x = 0; x < W; x++) + grid[y * W + x] = 1; + for (x = 0; x < W; x += 2) + grid[(y + FH - 1) * W + x] = 1; + } + for (x = 0; x < W; x += FW) { + for (y = 0; y < H; y++) + grid[y * W + x] = 1; + for (y = 0; y < H; y += 2) + grid[y * W + x + FW - 1] = 1; + } + for (y = 0; y < NR; y++) { + for (x = 0; x < NC; x++) { + int v = places[(NR - y - 1) * NC + x]; + //fprintf (stderr, "%4d", v); + if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7))))) + grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1; + } + //fprintf (stderr, "\n"); + } + for(y = H - 1; y >= 0; y--) { + int x; + for(x = 0; x < W; x++) { + if(grid[W * y + x]) { + set_module(symbol, (H - y) - 1, x); + } + } + symbol->row_height[(H - y) - 1] = 1; + } + free(grid); + free(places); + } + + symbol->rows = H; + symbol->width = W; + + return error_number; +} diff --git a/backend/dm200.h b/backend/dm200.h new file mode 100644 index 00000000..75de6072 --- /dev/null +++ b/backend/dm200.h @@ -0,0 +1,101 @@ +/* dm200.h - Handles Data Matrix ECC 200 */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 "common.h" + +#ifndef __IEC16022ECC200_H +#define __IEC16022ECC200_H +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#define MAXBARCODE 3116 + +#define DM_ASCII 1 +#define DM_C40 2 +#define DM_TEXT 3 +#define DM_X12 4 +#define DM_EDIFACT 5 +#define DM_BASE256 6 + +static int c40_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + +static int c40_value[] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, + 15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, + 22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; + +static int text_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 }; + +static int text_value[] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, + 15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, + 22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 }; + +static int intsymbol[] = { + 0,1,3,5,7,8,10,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,2,4,6,9,11,14 }; + +static int matrixH[] = { + 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48, + 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; + +static int matrixW[] = { + 10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44, + 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; + +static int matrixFH[] = { + 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24, + 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; + +static int matrixFW[] = { + 10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22, + 24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; + +static int matrixbytes[] = { + 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, + 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 }; + +static int matrixdatablock[] = { + 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, + 174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 }; + +static int matrixrsblock[] = { + 5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68, + 42, 56, 36, 48, 56, 68, 56, 68, 62, 62 }; + +#endif /* __IEC16022ECC200_H */ diff --git a/backend/dmatrix.c b/backend/dmatrix.c new file mode 100644 index 00000000..147a758e --- /dev/null +++ b/backend/dmatrix.c @@ -0,0 +1,1318 @@ +/* dmatrix.c - Handles Data Matrix 2-D symbology */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#ifdef _MSC_VER +#include +#endif +#include "dmatrix.h" +#include "common.h" +#ifdef __cplusplus +#include "dm200.h" +#else +extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length); +#endif + +#define SODIUM " 0123456789" +#define COBALT " ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define RUBIDIUM " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +#define NIOBIUM " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,-/" + +void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[], int length) +{ + int input_length, i, debug = 0; + char xor_register[17]; + int machine_cycles; + char input_bit, out1, out2, out3; + + input_length = length; + +#ifndef _MSC_VER + char precrc_bitstream[(input_length * 8) + 18]; + char precrc_bitstream_reversed[(input_length * 8) + 18]; +#else + char* precrc_bitstream = (char*)_alloca((input_length * 8) + 18); + char* precrc_bitstream_reversed = (char*)_alloca((input_length * 8) + 18); +#endif + + switch(scheme) { + case 11: strcpy(precrc_bitstream, "0000000100000000"); if(debug) { printf("Scheme 11\n"); } break; + case 27: strcpy(precrc_bitstream, "0000001000000000"); if(debug) { printf("Scheme 27\n"); } break; + case 41: strcpy(precrc_bitstream, "0000001100000000"); if(debug) { printf("Scheme 41\n"); } break; + case 37: strcpy(precrc_bitstream, "0000010000000000"); if(debug) { printf("Scheme 37\n"); } break; + default: strcpy(precrc_bitstream, "0000010100000000"); if(debug) { printf("Scheme DE\n"); } break; + } + + for(i = 0; i < input_length; i++) { + if(source[i] & 0x80) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x40) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x20) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x10) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x08) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x04) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x02) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + if(source[i] & 0x01) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); } + } + if(debug) { printf("CRC bitstream:\n%s\n", precrc_bitstream); } + + /* pre-CRC bit stream byte reversal */ + for(i = 0; i < (input_length + 2); i++) { + precrc_bitstream_reversed[0 + (i * 8)] = precrc_bitstream[7 + (i * 8)]; + precrc_bitstream_reversed[1 + (i * 8)] = precrc_bitstream[6 + (i * 8)]; + precrc_bitstream_reversed[2 + (i * 8)] = precrc_bitstream[5 + (i * 8)]; + precrc_bitstream_reversed[3 + (i * 8)] = precrc_bitstream[4 + (i * 8)]; + precrc_bitstream_reversed[4 + (i * 8)] = precrc_bitstream[3 + (i * 8)]; + precrc_bitstream_reversed[5 + (i * 8)] = precrc_bitstream[2 + (i * 8)]; + precrc_bitstream_reversed[6 + (i * 8)] = precrc_bitstream[1 + (i * 8)]; + precrc_bitstream_reversed[7 + (i * 8)] = precrc_bitstream[0 + (i * 8)]; + } + precrc_bitstream_reversed[strlen(precrc_bitstream)] = '\0'; + machine_cycles = strlen(precrc_bitstream_reversed); + if(debug) { printf("Reversed CRC bitstream:\n%s\n", precrc_bitstream_reversed); } + + /* Start up the machine */ + for(i = 0; i < 16; i++) { + xor_register[i] = '0'; + } + input_bit = precrc_bitstream_reversed[0]; + if(input_bit != xor_register[15]) { out1 = '1'; } else { out1 = '0'; } + if(input_bit != xor_register[11]) { out2 = '1'; } else { out2 = '0'; } + if(input_bit != xor_register[4]) { out3 = '1'; } else { out3 = '0'; } + + for(i = 0; i < machine_cycles; i++) { + xor_register[15] = xor_register[14]; + xor_register[14] = xor_register[13]; + xor_register[13] = xor_register[12]; + xor_register[12] = out2; + xor_register[11] = xor_register[10]; + xor_register[10] = xor_register[9]; + xor_register[9] = xor_register[8]; + xor_register[8] = xor_register[7]; + xor_register[7] = xor_register[6]; + xor_register[6] = xor_register[5]; + xor_register[5] = out3; + xor_register[4] = xor_register[3]; + xor_register[3] = xor_register[2]; + xor_register[2] = xor_register[1]; + xor_register[1] = xor_register[0]; + xor_register[0] = out1; + input_bit = precrc_bitstream_reversed[(i + 1)]; + if(input_bit != xor_register[15]) { out1 = '1'; } else { out1 = '0'; } + if(out1 != xor_register[11]) { out2 = '1'; } else { out2 = '0'; } + if(out1 != xor_register[4]) { out3 = '1'; } else { out3 = '0'; } + } + + for(i = 0; i < 16; i++) { + data_prefix_bitstream[i + 5] = xor_register[15 - i]; + } + data_prefix_bitstream[16 + 5] = '\0'; + if(debug) { printf("Data Prefix:\n%s\n", data_prefix_bitstream); } + + return; +} + +void i1_base11(char binary_string[], unsigned char source[], int length) +{ + int input_length, blocks, remainder, i, j; + char block_binary[22]; + int block_value, c[6], weight[6]; + int binary_posn; + + input_length = length; + binary_posn = strlen(binary_string); + blocks = input_length / 6; + remainder = input_length % 6; + + weight[0] = 1; + weight[1] = 11; + weight[2] = 121; + weight[3] = 1331; + weight[4] = 14641; + weight[5] = 161051; + + for(i = 0; i < blocks; i++) { + strcpy(block_binary, ""); + block_value = 0; + binary_posn = strlen(binary_string); + for(j = 0; j < 6; j++) { + c[j] = posn(SODIUM, source[(i * 6) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + } + + strcpy(block_binary, ""); + block_value = 0; + binary_posn = strlen(binary_string); + for(j = 0; j < remainder; j++) { + c[j] = posn(SODIUM, source[(i * 6) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + switch(remainder) { + case 5: + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 4: + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 3: + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 2: + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 1: + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + default: + break; + } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + + return; +} + +void i2_base27(char binary_string[], unsigned char source[], int length) +{ + int input_length, blocks, remainder, i, j; + char block_binary[25]; + int block_value, c[5], weight[5]; + int binary_posn; + + input_length = length; + blocks = input_length / 5; + remainder = input_length % 5; + binary_posn = strlen(binary_string); + + weight[0] = 1; + weight[1] = 27; + weight[2] = 729; + weight[3] = 19683; + weight[4] = 531441; + + for(i = 0; i < blocks; i++) { + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < 5; j++) { + c[j] = posn(COBALT, source[(i * 5) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + if(block_value & 0x800000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + } + + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < remainder; j++) { + c[j] = posn(COBALT, source[(i * 5) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + switch(remainder) { + case 4: + if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 3: + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 2: + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 1: + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + default: + break; + } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + + return; +} + +void i3_base37(char binary_string[], unsigned char source[], int length) +{ + int input_length, blocks, remainder, i, j; + char block_binary[22]; + int block_value, c[6], weight[6]; + int binary_posn; + + input_length = length; + blocks = input_length / 4; + remainder = input_length % 4; + binary_posn = strlen(binary_string); + + weight[0] = 1; + weight[1] = 37; + weight[2] = 1369; + weight[3] = 50653; + + for(i = 0; i < blocks; i++) { + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < 4; j++) { + c[j] = posn(RUBIDIUM, source[(i * 4) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + } + + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < remainder; j++) { + c[j] = posn(RUBIDIUM, source[(i * 4) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + switch(remainder) { + case 3: + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 2: + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 1: + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + default: + break; + } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + + return; +} + +void i4_base41(char binary_string[], unsigned char source[], int length) +{ + int input_length, blocks, remainder, i, j; + char block_binary[23]; + int block_value, c[6], weight[6]; + int binary_posn; + + input_length = length; + blocks = input_length / 4; + remainder = input_length % 4; + binary_posn = strlen(binary_string); + + weight[0] = 1; + weight[1] = 41; + weight[2] = 1681; + weight[3] = 68921; + + for(i = 0; i < blocks; i++) { + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < 4; j++) { + c[j] = posn(NIOBIUM, source[(i * 4) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + if(block_value & 0x200000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + } + + strcpy(block_binary, ""); + block_value = 0; + for(j = 0; j < remainder; j++) { + c[j] = posn(NIOBIUM, source[(i * 4) + j]); + c[j] *= weight[j]; + block_value += c[j]; + } + + switch(remainder) { + case 3: + if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 2: + if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + case 1: + if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + default: + break; + } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + + return; +} + +void base128(char binary_string[], unsigned char source[], int length) +{ + int i, j, input_length; + char block_binary[9]; + int binary_posn; + + input_length = length; + binary_posn = strlen(binary_string); + + for(i = 0; i < input_length; i++) { + strcpy(block_binary, ""); + + if(source[i] & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + if(source[i] & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } + + for(j = 0; j < strlen(block_binary); j++) { + binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j]; + } + binary_string[strlen(block_binary) + binary_posn] = '\0'; + binary_posn = strlen(binary_string); + } + + return; +} + +void protect_ecc000(char protected_stream[], char unprotected_stream[]) +{ + /* ECC 000 - No processing needed */ + + strcpy(protected_stream, unprotected_stream); +} + +void protect_ecc050(char protected_stream[], char unprotected_stream[]) +{ + /* ECC 050 - 4-3-3 convolutional code */ + /* State machine illustrated in figure K1 */ + char top_reg[4]; + char mid_reg[4]; + char low_reg[4]; + char u1, u2, u3; + char output[6]; + char gate_input[8]; + int i, blocks, j, count; + + strcpy(protected_stream, ""); + + for(i = 0; i < 3; i++) { + top_reg[i] = '0'; + mid_reg[i] = '0'; + low_reg[i] = '0'; + } + + for(i = 0; i < (strlen(unprotected_stream) % 3); i++){ + concat(unprotected_stream, "0"); + } + blocks = strlen(unprotected_stream) / 3; + blocks += 3; + for(i = 0; i < blocks; i++) { + if(i < (blocks - 3)) { + u1 = unprotected_stream[3 * i]; + u2 = unprotected_stream[(3 * i) + 1]; + u3 = unprotected_stream[(3 * i) + 2]; + } else { + u1 = '0'; + u2 = '0'; + u3 = '0'; + } + + /* Gate 1 */ + for(j = 0; j < 8; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u1; + gate_input[1] = mid_reg[2]; + gate_input[2] = low_reg[0]; + gate_input[3] = low_reg[1]; + gate_input[4] = low_reg[2]; + + count = 0; + for(j = 0; j < 5; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; } + + /* Gate 2 */ + for(j = 0; j < 8; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = top_reg[1]; + gate_input[1] = top_reg[2]; + gate_input[2] = u2; + gate_input[3] = mid_reg[0]; + gate_input[4] = mid_reg[2]; + + count = 0; + for(j = 0; j < 5; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; } + + /* Gate 3 */ + for(j = 0; j < 8; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = top_reg[0]; + gate_input[1] = top_reg[1]; + gate_input[2] = top_reg[2]; + gate_input[3] = mid_reg[0]; + gate_input[4] = u3; + gate_input[5] = low_reg[0]; + + count = 0; + for(j = 0; j < 6; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; } + + /* Gate 4 */ + for(j = 0; j < 8; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u1; + gate_input[1] = top_reg[0]; + gate_input[2] = u2; + gate_input[3] = mid_reg[0]; + gate_input[4] = mid_reg[1]; + gate_input[5] = u3; + gate_input[6] = low_reg[0]; + gate_input[7] = low_reg[2]; + + count = 0; + for(j = 0; j < 8; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[3] = '1'; } else { output[3] = '0'; } + + output[4] = '\0'; + + concat(protected_stream, output); + + /* Shift registers right */ + top_reg[2] = top_reg[1]; + top_reg[1] = top_reg[0]; + top_reg[0] = u1; + mid_reg[2] = mid_reg[1]; + mid_reg[1] = mid_reg[0]; + mid_reg[0] = u2; + low_reg[2] = low_reg[1]; + low_reg[1] = low_reg[0]; + low_reg[0] = u3; + } +} + +void protect_ecc080(char protected_stream[], char unprotected_stream[]) +{ + /* ECC 080 - 3-2-11 convolutional code */ + /* State machine illustrated in figure K2 */ + char top_reg[12]; + char low_reg[12]; + char u1, u2; + char output[4]; + char gate_input[12]; + int i, j, count, blocks; + + strcpy(protected_stream, ""); + + for(i = 0; i < 12; i++) { + top_reg[i] = '0'; + low_reg[i] = '0'; + } + + for(i = 0; i < (strlen(unprotected_stream) % 2); i++){ + concat(unprotected_stream, "0"); + } + blocks = strlen(unprotected_stream) / 2; + blocks += 11; + for(i = 0; i < blocks; i++) { + if(i < (blocks - 11)) { + u1 = unprotected_stream[2 * i]; + u2 = unprotected_stream[(2 * i) + 1]; + } else { + u1 = '0'; + u2 = '0'; + } + + /* Gate 1 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u1; + gate_input[1] = top_reg[0]; + gate_input[2] = top_reg[2]; + gate_input[3] = top_reg[4]; + gate_input[4] = top_reg[5]; + gate_input[5] = top_reg[6]; + gate_input[6] = top_reg[9]; + gate_input[7] = low_reg[2]; + gate_input[8] = low_reg[6]; + gate_input[9] = low_reg[7]; + gate_input[10] = low_reg[10]; + + count = 0; + for(j = 0; j < 11; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; } + + /* Gate 2 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = top_reg[0]; + gate_input[1] = top_reg[3]; + gate_input[2] = top_reg[4]; + gate_input[3] = top_reg[7]; + gate_input[4] = top_reg[8]; + gate_input[5] = top_reg[9]; + gate_input[6] = u2; + gate_input[7] = low_reg[2]; + gate_input[8] = low_reg[5]; + gate_input[9] = low_reg[7]; + gate_input[10] = low_reg[8]; + + count = 0; + for(j = 0; j < 11; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; } + + /* Gate 3 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u1; + gate_input[1] = top_reg[4]; + gate_input[2] = top_reg[5]; + gate_input[3] = top_reg[6]; + gate_input[4] = u2; + gate_input[5] = low_reg[0]; + gate_input[6] = low_reg[1]; + gate_input[7] = low_reg[3]; + gate_input[8] = low_reg[6]; + gate_input[9] = low_reg[8]; + gate_input[10] = low_reg[10]; + + count = 0; + for(j = 0; j < 11; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; } + + output[3] = '\0'; + + concat(protected_stream, output); + + /* Shift registers right */ + top_reg[9] = top_reg[8]; + top_reg[8] = top_reg[7]; + top_reg[7] = top_reg[6]; + top_reg[6] = top_reg[5]; + top_reg[5] = top_reg[4]; + top_reg[4] = top_reg[3]; + top_reg[3] = top_reg[2]; + top_reg[2] = top_reg[1]; + top_reg[1] = top_reg[0]; + top_reg[0] = u1; + low_reg[10] = low_reg[9]; + low_reg[9] = low_reg[8]; + low_reg[8] = low_reg[7]; + low_reg[7] = low_reg[6]; + low_reg[6] = low_reg[5]; + low_reg[5] = low_reg[4]; + low_reg[4] = low_reg[3]; + low_reg[3] = low_reg[2]; + low_reg[2] = low_reg[1]; + low_reg[1] = low_reg[0]; + low_reg[0] = u2; + + } +} + +void protect_ecc100(char protected_stream[], char unprotected_stream[]) +{ + /* ECC 100 - 2-1-15 convolutional code */ + /* State machine illustrated in figure k3 */ + char reg[16]; + char u; + char output[3]; + char gate_input[10]; + int i, j, count, blocks; + + strcpy(protected_stream, ""); + + for(i = 0; i < 16; i++) { + reg[i] = '0'; + } + + blocks = strlen(unprotected_stream); + blocks += 15; + for(i = 0; i < blocks; i++) { + if(i < (blocks - 15)) { + u = unprotected_stream[i]; + } else { + u = '0'; + } + + /* Gate 1 */ + for(j = 0; j < 10; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[1]; + gate_input[2] = reg[4]; + gate_input[3] = reg[5]; + gate_input[4] = reg[6]; + gate_input[5] = reg[7]; + gate_input[6] = reg[8]; + gate_input[7] = reg[9]; + gate_input[8] = reg[14]; + + count = 0; + for(j = 0; j < 9; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; } + + /* Gate 2 */ + for(j = 0; j < 10; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[0]; + gate_input[2] = reg[2]; + gate_input[3] = reg[3]; + gate_input[4] = reg[5]; + gate_input[5] = reg[10]; + gate_input[6] = reg[12]; + gate_input[7] = reg[13]; + gate_input[8] = reg[14]; + + count = 0; + for(j = 0; j < 9; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; } + + output[2] = '\0'; + + concat(protected_stream, output); + + /* Shift register right */ + reg[14] = reg[13]; + reg[13] = reg[12]; + reg[12] = reg[11]; + reg[11] = reg[10]; + reg[10] = reg[9]; + reg[9] = reg[8]; + reg[8] = reg[7]; + reg[7] = reg[6]; + reg[6] = reg[5]; + reg[5] = reg[4]; + reg[4] = reg[3]; + reg[3] = reg[2]; + reg[2] = reg[1]; + reg[1] = reg[0]; + reg[0] = u; + } +} + +void protect_ecc140(char protected_stream[], char unprotected_stream[]) +{ + /* ECC 140 - 4-1-13 convolutional coding */ + /* State machine illustrated in figure k3 */ + char reg[13]; + char u; + char output[5]; + char gate_input[12]; + int i, j, count, blocks; + + strcpy(protected_stream, ""); + + for(i = 0; i < 13; i++) { + reg[i] = '0'; + } + + blocks = strlen(unprotected_stream); + blocks += 13; + for(i = 0; i < blocks; i++) { + if(i < (blocks - 13)) { + u = unprotected_stream[i]; + } else { + u = '0'; + } + + /* Gate 1 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[3]; + gate_input[2] = reg[6]; + gate_input[3] = reg[9]; + gate_input[4] = reg[11]; + gate_input[5] = reg[12]; + + count = 0; + for(j = 0; j < 6; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; } + + /* Gate 2 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[2]; + gate_input[2] = reg[3]; + gate_input[3] = reg[6]; + gate_input[4] = reg[7]; + gate_input[5] = reg[8]; + gate_input[6] = reg[9]; + gate_input[7] = reg[10]; + gate_input[8] = reg[12]; + + count = 0; + for(j = 0; j < 9; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; } + + /* Gate 3 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[0]; + gate_input[2] = reg[1]; + gate_input[3] = reg[3]; + gate_input[4] = reg[4]; + gate_input[5] = reg[6]; + gate_input[6] = reg[8]; + gate_input[7] = reg[10]; + gate_input[8] = reg[11]; + gate_input[9] = reg[12]; + + count = 0; + for(j = 0; j < 10; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; } + + /* Gate 4 */ + for(j = 0; j < 12; j++) { + gate_input[j] = '0'; + } + + gate_input[0] = u; + gate_input[1] = reg[0]; + gate_input[2] = reg[1]; + gate_input[3] = reg[3]; + gate_input[4] = reg[4]; + gate_input[5] = reg[6]; + gate_input[6] = reg[8]; + gate_input[7] = reg[9]; + gate_input[8] = reg[10]; + gate_input[9] = reg[11]; + gate_input[10] = reg[12]; + + count = 0; + for(j = 0; j < 11; j++) { + if(gate_input[j] == '1') { + count++; + } + } + if((count & 0x01) == 0x01) { output[3] = '1'; } else { output[3] = '0'; } + + output[4] = '\0'; + + concat(protected_stream, output); + + /* Shift register right */ + reg[12] = reg[11]; + reg[11] = reg[10]; + reg[10] = reg[9]; + reg[9] = reg[8]; + reg[8] = reg[7]; + reg[7] = reg[6]; + reg[6] = reg[5]; + reg[5] = reg[4]; + reg[4] = reg[3]; + reg[3] = reg[2]; + reg[2] = reg[1]; + reg[1] = reg[0]; + reg[0] = u; + } + +} + +int matrix89(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int i, j, input_length, scheme; + char unprotected_stream[2210]; + char data_prefix_bitstream[31]; + char protected_stream[6630]; + char unrandomized_stream[2210]; + char master_random_stream[2214]; + char randomized_stream[2210]; + char header[20]; + int symbol_size, hex_segment, width; + int error_number; + + input_length = length; + error_number = 0; + + symbol_size = 0; + for(i = 0; i < input_length; i++) { + if(source[i] > 127) { + strcpy(symbol->errtxt, "Data Matrix ECC 000 - 140 doesn't support extended ASCII"); + return ERROR_INVALID_DATA; + } + } + + /* Decide which encoding scheme to use */ + scheme = 128; + if(!(is_sane(NIOBIUM, source, length))) { scheme = 41; } + if(!(is_sane(RUBIDIUM, source, length))) { scheme = 37; } + if(!(is_sane(COBALT, source, length))) { scheme = 27; } + if(!(is_sane(SODIUM, source, length))) { scheme = 11; } + + /* Data Prefix Bit Stream = Format ID + CRC + Data Length */ + + /* Format ID (5 bits) */ + switch(scheme) { + case 11: strcpy(data_prefix_bitstream, "00000"); break; + case 27: strcpy(data_prefix_bitstream, "00001"); break; + case 37: strcpy(data_prefix_bitstream, "00011"); break; + case 41: strcpy(data_prefix_bitstream, "00010"); break; + default: strcpy(data_prefix_bitstream, "00100"); break; + } + + /* CRC Value (16 bit) */ + crc_machine(data_prefix_bitstream, scheme, source, length); + + /* Data length (9 bit) */ + if(input_length & 0x01) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x02) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x04) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x08) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x10) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x20) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x40) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x80) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + if(input_length & 0x100) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); } + + /* Unprotected Bit Stream = Data Prefix Bitstream + Encoded Data */ + + strcpy(unprotected_stream, data_prefix_bitstream); + + switch(scheme) { + case 11: + if(input_length >= 618) { + strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG; + } + break; + case 27: + if(input_length >= 450) { + strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG; + } + break; + case 37: + if(input_length >= 412) { + strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG; + } + break; + case 41: + if(input_length >= 396) { + strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG; + } + break; + case 128: + if(input_length >= 311) { + strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG; + } + break; + } + + switch(scheme) { + case 11: i1_base11(unprotected_stream, source, length); break; + case 27: i2_base27(unprotected_stream, source, length); break; + case 37: i3_base37(unprotected_stream, source, length); break; + case 41: i4_base41(unprotected_stream, source, length); break; + default: base128(unprotected_stream, source, length); break; + } + + /* Header (ECC Bit field) LSB first */ + switch(symbol->option_1) { + case 2: strcpy(header, "0111111"); break; /* ECC 000 */ + case 3: strcpy(header, "0111000000000111000"); break; /* ECC 050 */ + case 4: strcpy(header, "0111000000111000111"); break; /* ECC 080 */ + case 5: strcpy(header, "0111000000111111111"); break; /* ECC 100 */ + case 6: strcpy(header, "0111000111000111111"); break; /* ECC 140 */ + } + + /* Generate Protected Bit Stream */ + switch(symbol->option_1) { + case 2: protect_ecc000(protected_stream, unprotected_stream); break; + case 3: protect_ecc050(protected_stream, unprotected_stream); break; + case 4: protect_ecc080(protected_stream, unprotected_stream); break; + case 5: protect_ecc100(protected_stream, unprotected_stream); break; + case 6: protect_ecc140(protected_stream, unprotected_stream); break; + } + + if((strlen(protected_stream) + strlen(header)) > 2209) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + + /* Construct Unrandomized Bit Stream */ + strcpy(unrandomized_stream, header); + concat(unrandomized_stream, protected_stream); + + /* Determine Symbol Size */ + for(i = 20; i >= 0; i--) { + if(MatrixMaxCapacities[i] > strlen(unrandomized_stream)) { + symbol_size = i; + } + } + + if((symbol->option_2 < 0) || (symbol->option_2 > 21)) { + strcpy(symbol->errtxt, "Invalid symbol size"); + error_number = WARN_INVALID_OPTION; + symbol->option_2 = 0; + } + + if((symbol->option_2 - 1) > symbol_size) { + symbol_size = (symbol->option_2 - 1); + } + + if(((symbol->option_2 - 1) < symbol_size) && (symbol->option_2 != 0)) { + strcpy(symbol->errtxt, "Unable to fit data in specified symbol size"); + error_number = WARN_INVALID_OPTION; + } + + /* Add trailer (pad bits) */ + input_length = strlen(unrandomized_stream); + for(i = input_length; i < MatrixMaxCapacities[symbol_size]; i++) { + concat(unrandomized_stream, "0"); + } + + /* Load master random stream */ + strcpy(master_random_stream, ""); + for(i = 0; i < 276; i++) { + hex_segment = MasterRandomStream[i]; + if(hex_segment & 0x80) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x40) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x20) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x10) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x08) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x04) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x02) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + if(hex_segment & 0x01) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); } + } + + /* Randomizing Algorithm */ + + strcpy(randomized_stream, ""); + for(i = 0; i < strlen(unrandomized_stream); i++) { + if(unrandomized_stream[i] != master_random_stream[i]) { + concat(randomized_stream, "1"); + } else { + concat(randomized_stream, "0"); + } + } + + /* Placement Algorithm */ + width = (symbol_size * 2) + 7; + + symbol->row_height[0] = 1; + /* Fill corners */ + set_module(symbol, 0, 0); + set_module(symbol, 0, width + 1); + set_module(symbol, width + 1, 0); + set_module(symbol, width + 1, width + 1); + for(i = 0; i < width; i++) { + /* Fill sides */ + set_module(symbol, i + 1, 0); + set_module(symbol, width + 1, i + 1); + if((i % 2) == 0) { + set_module(symbol, i, width + 1); + set_module(symbol, 0, i); + } + for(j = 0; j < width; j++) { + + switch(symbol_size) { + case 0: if(randomized_stream[tableh1[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 1: if(randomized_stream[tableh2[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 2: if(randomized_stream[tableh3[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 3: if(randomized_stream[tableh4[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 4: if(randomized_stream[tableh5[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 5: if(randomized_stream[tableh6[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 6: if(randomized_stream[tableh7[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 7: if(randomized_stream[tableh8[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 8: if(randomized_stream[tableh9[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 9: if(randomized_stream[tableh10[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 10: if(randomized_stream[tableh11[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 11: if(randomized_stream[tableh12[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 12: if(randomized_stream[tableh13[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 13: if(randomized_stream[tableh14[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 14: if(randomized_stream[tableh15[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 15: if(randomized_stream[tableh16[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 16: if(randomized_stream[tableh17[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 17: if(randomized_stream[tableh18[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 18: if(randomized_stream[tableh19[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 19: if(randomized_stream[tableh20[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + case 20: if(randomized_stream[tableh21[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break; + } + } + symbol->row_height[i + 1] = 1; + } + + symbol->row_height[width + 1] = 1; + symbol->rows = width + 2; + symbol->width = width + 2; + + return error_number; +} + +int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int error_number; + + if(symbol->option_1 <= 1) { + /* ECC 200 */ + error_number = data_matrix_200(symbol, source, length); + } else { + /* ECC 000 - 140 */ + error_number = matrix89(symbol, source, length); + } + + return error_number; +} diff --git a/backend/dmatrix.h b/backend/dmatrix.h new file mode 100644 index 00000000..3bc364db --- /dev/null +++ b/backend/dmatrix.h @@ -0,0 +1,671 @@ +/* dmatrix.h - Data Matrix ECC 000 - 150 tables */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* Data taken from ISO/IEC 16022:2006 Annex H "ECC 000 - 140 data module placement grids" */ + +int tableh1[] = { /* 7 x 7 data */ + 2,45,10,38,24,21,1, + 12,40,26,5,33,19,47, + 22,31,29,15,43,8,36, + 34,20,48,13,41,27,6, + 44,9,37,23,17,30,16, + 39,25,4,32,18,46,11, + 0,28,14,42,7,35,3 +}; + +int tableh2[] = { /* 9 x 9 data */ + 2,19,55,10,46,28,64,73,1, + 62,17,53,35,71,8,80,44,26, + 49,31,67,4,76,40,22,58,13, + 69,6,78,42,24,60,15,51,33, + 74,38,20,56,11,47,29,65,37, + 25,61,16,52,34,70,7,79,43, + 12,48,30,66,63,75,39,21,57, + 32,68,5,77,41,23,59,14,50, + 0,72,36,18,54,9,45,27,3 +}; + +int tableh3[] = { /* 11 x 11 data */ + 2,26,114,70,15,103,59,37,81,4,1, + 117,73,18,106,62,40,84,7,95,51,29, + 12,100,56,34,78,92,89,45,23,111,67, + 65,43,87,10,98,54,32,120,76,21,109, + 82,5,93,49,27,115,71,16,104,60,38, + 96,52,30,118,74,19,107,63,41,85,8, + 24,112,68,13,101,57,35,79,48,90,46, + 75,20,108,64,42,86,9,97,53,31,119, + 102,58,36,80,77,91,47,25,113,69,14, + 39,83,6,94,50,28,116,72,17,105,61, + 0,88,44,22,110,66,11,99,55,33,3 +}; + +int tableh4[] = { /* 13 x 13 data */ + 2,159,29,133,81,16,120,68,42,146,94,91,1, + 37,141,89,24,128,76,50,154,102,11,115,63,167, + 83,18,122,70,44,148,96,5,109,57,161,31,135, + 125,73,47,151,99,8,112,60,164,34,138,86,21, + 40,144,92,107,105,53,157,27,131,79,14,118,66, + 103,12,116,64,168,38,142,90,25,129,77,51,155, + 110,58,162,32,136,84,19,123,71,45,149,97,6, + 165,35,139,87,22,126,74,48,152,100,9,113,61, + 132,80,15,119,67,41,145,93,55,106,54,158,28, + 23,127,75,49,153,101,10,114,62,166,36,140,88, + 69,43,147,95,4,108,56,160,30,134,82,17,121, + 150,98,7,111,59,163,33,137,85,20,124,72,46, + 0,104,52,156,26,130,78,13,117,65,39,143,3 +}; + +int tableh5[] = { /* 15 x 15 data */ + 2,187,37,157,97,217,22,142,82,202,52,172,112,7,1, + 41,161,101,221,26,146,86,206,56,176,116,11,131,71,191, + 93,213,18,138,78,198,48,168,108,105,123,63,183,33,153, + 28,148,88,208,58,178,118,13,133,73,193,43,163,103,223, + 80,200,50,170,110,5,125,65,185,35,155,95,215,20,140, + 54,174,114,9,129,69,189,39,159,99,219,24,144,84,204, + 106,127,121,61,181,31,151,91,211,16,136,76,196,46,166, + 134,74,194,44,164,104,224,29,149,89,209,59,179,119,14, + 186,36,156,96,216,21,141,81,201,51,171,111,6,126,66, + 160,100,220,25,145,85,205,55,175,115,10,130,70,190,40, + 212,17,137,77,197,47,167,107,67,122,62,182,32,152,92, + 147,87,207,57,177,117,12,132,72,192,42,162,102,222,27, + 199,49,169,109,4,124,64,184,34,154,94,214,19,139,79, + 173,113,8,128,68,188,38,158,98,218,23,143,83,203,53, + 0,120,60,180,30,150,90,210,15,135,75,195,45,165,3 +}; + +int tableh6[] = { /* 17 x 17 data */ + 2,69,205,35,171,103,239,18,154,86,222,52,188,120,256,273,1, + 220,50,186,118,254,33,169,101,237,67,203,135,271,16,288,152,84, + 178,110,246,25,161,93,229,59,195,127,263,8,280,144,76,212,42, + 250,29,165,97,233,63,199,131,267,12,284,148,80,216,46,182,114, + 157,89,225,55,191,123,259,4,276,140,72,208,38,174,106,242,21, + 235,65,201,133,269,14,286,150,82,218,48,184,116,252,31,167,99, + 193,125,261,6,278,142,74,210,40,176,108,244,23,159,91,227,57, + 265,10,282,146,78,214,44,180,112,248,27,163,95,231,61,197,129, + 274,138,70,206,36,172,104,240,19,155,87,223,53,189,121,257,137, + 83,219,49,185,117,253,32,168,100,236,66,202,134,270,15,287,151, + 41,177,109,245,24,160,92,228,58,194,126,262,7,279,143,75,211, + 113,249,28,164,96,232,62,198,130,266,11,283,147,79,215,45,181, + 20,156,88,224,54,190,122,258,255,275,139,71,207,37,173,105,241, + 98,234,64,200,132,268,13,285,149,81,217,47,183,115,251,30,166, + 56,192,124,260,5,277,141,73,209,39,175,107,243,22,158,90,226, + 128,264,9,281,145,77,213,43,179,111,247,26,162,94,230,60,196, + 0,272,136,68,204,34,170,102,238,17,153,85,221,51,187,119,3 +}; + +int tableh7[] = { /* 19 x 19 data */ + 2,82,234,44,348,196,120,272,25,329,177,101,253,63,215,139,291,6,1, + 239,49,353,201,125,277,30,334,182,106,258,68,220,144,296,11,315,163,87, + 343,191,115,267,20,324,172,96,248,58,210,134,286,310,305,153,77,229,39, + 132,284,37,341,189,113,265,75,227,151,303,18,322,170,94,246,56,360,208, + 28,332,180,104,256,66,218,142,294,9,313,161,85,237,47,351,199,123,275, + 185,109,261,71,223,147,299,14,318,166,90,242,52,356,204,128,280,33,337, + 251,61,213,137,289,4,308,156,80,232,42,346,194,118,270,23,327,175,99, + 225,149,301,16,320,168,92,244,54,358,206,130,282,35,339,187,111,263,73, + 292,7,311,159,83,235,45,349,197,121,273,26,330,178,102,254,64,216,140, + 316,164,88,240,50,354,202,126,278,31,335,183,107,259,69,221,145,297,12, + 78,230,40,344,192,116,268,21,325,173,97,249,59,211,135,287,158,306,154, + 55,359,207,131,283,36,340,188,112,264,74,226,150,302,17,321,169,93,245, + 198,122,274,27,331,179,103,255,65,217,141,293,8,312,160,84,236,46,350, + 279,32,336,184,108,260,70,222,146,298,13,317,165,89,241,51,355,203,127, + 326,174,98,250,60,212,136,288,285,307,155,79,231,41,345,193,117,269,22, + 110,262,72,224,148,300,15,319,167,91,243,53,357,205,129,281,34,338,186, + 62,214,138,290,5,309,157,81,233,43,347,195,119,271,24,328,176,100,252, + 143,295,10,314,162,86,238,48,352,200,124,276,29,333,181,105,257,67,219, + 0,304,152,76,228,38,342,190,114,266,19,323,171,95,247,57,209,133,3 +}; + +int tableh8[] = { /* 21 x 21 data */ + 2,88,424,256,46,382,214,130,298,25,361,193,109,277,67,403,235,151,319,4,1, + 437,269,59,395,227,143,311,38,374,206,122,290,80,416,248,164,332,17,353,185,101, + 49,385,217,133,301,28,364,196,112,280,70,406,238,154,322,7,343,175,91,427,259, + 222,138,306,33,369,201,117,285,75,411,243,159,327,12,348,180,96,432,264,54,390, + 295,22,358,190,106,274,64,400,232,148,316,340,337,169,85,421,253,43,379,211,127, + 377,209,125,293,83,419,251,167,335,20,356,188,104,440,272,62,398,230,146,314,41, + 115,283,73,409,241,157,325,10,346,178,94,430,262,52,388,220,136,304,31,367,199, + 78,414,246,162,330,15,351,183,99,435,267,57,393,225,141,309,36,372,204,120,288, + 236,152,320,5,341,173,89,425,257,47,383,215,131,299,26,362,194,110,278,68,404, + 333,18,354,186,102,438,270,60,396,228,144,312,39,375,207,123,291,81,417,249,165, + 344,176,92,428,260,50,386,218,134,302,29,365,197,113,281,71,407,239,155,323,8, + 97,433,265,55,391,223,139,307,34,370,202,118,286,76,412,244,160,328,13,349,181, + 254,44,380,212,128,296,23,359,191,107,275,65,401,233,149,317,172,338,170,86,422, + 397,229,145,313,40,376,208,124,292,82,418,250,166,334,19,355,187,103,439,271,61, + 135,303,30,366,198,114,282,72,408,240,156,324,9,345,177,93,429,261,51,387,219, + 35,371,203,119,287,77,413,245,161,329,14,350,182,98,434,266,56,392,224,140,308, + 192,108,276,66,402,234,150,318,315,339,171,87,423,255,45,381,213,129,297,24,360, + 289,79,415,247,163,331,16,352,184,100,436,268,58,394,226,142,310,37,373,205,121, + 405,237,153,321,6,342,174,90,426,258,48,384,216,132,300,27,363,195,111,279,69, + 158,326,11,347,179,95,431,263,53,389,221,137,305,32,368,200,116,284,74,410,242, + 0,336,168,84,420,252,42,378,210,126,294,21,357,189,105,273,63,399,231,147,3 +}; + +int tableh9[] = { /* 23 x 23 data */ + 2,102,470,286,56,424,240,148,516,332,33,401,217,125,493,309,79,447,263,171,355,10,1, + 476,292,62,430,246,154,522,338,39,407,223,131,499,315,85,453,269,177,361,16,384,200,108, + 50,418,234,142,510,326,27,395,211,119,487,303,73,441,257,165,349,4,372,188,96,464,280, + 249,157,525,341,42,410,226,134,502,318,88,456,272,180,364,19,387,203,111,479,295,65,433, + 513,329,30,398,214,122,490,306,76,444,260,168,352,7,375,191,99,467,283,53,421,237,145, + 36,404,220,128,496,312,82,450,266,174,358,13,381,197,105,473,289,59,427,243,151,519,335, + 208,116,484,300,70,438,254,162,346,378,369,185,93,461,277,47,415,231,139,507,323,24,392, + 505,321,91,459,275,183,367,22,390,206,114,482,298,68,436,252,160,528,344,45,413,229,137, + 80,448,264,172,356,11,379,195,103,471,287,57,425,241,149,517,333,34,402,218,126,494,310, + 270,178,362,17,385,201,109,477,293,63,431,247,155,523,339,40,408,224,132,500,316,86,454, + 350,5,373,189,97,465,281,51,419,235,143,511,327,28,396,212,120,488,304,74,442,258,166, + 388,204,112,480,296,66,434,250,158,526,342,43,411,227,135,503,319,89,457,273,181,365,20, + 100,468,284,54,422,238,146,514,330,31,399,215,123,491,307,77,445,261,169,353,8,376,192, + 290,60,428,244,152,520,336,37,405,221,129,497,313,83,451,267,175,359,14,382,198,106,474, + 416,232,140,508,324,25,393,209,117,485,301,71,439,255,163,347,194,370,186,94,462,278,48, + 159,527,343,44,412,228,136,504,320,90,458,274,182,366,21,389,205,113,481,297,67,435,251, + 331,32,400,216,124,492,308,78,446,262,170,354,9,377,193,101,469,285,55,423,239,147,515, + 406,222,130,498,314,84,452,268,176,360,15,383,199,107,475,291,61,429,245,153,521,337,38, + 118,486,302,72,440,256,164,348,345,371,187,95,463,279,49,417,233,141,509,325,26,394,210, + 317,87,455,271,179,363,18,386,202,110,478,294,64,432,248,156,524,340,41,409,225,133,501, + 443,259,167,351,6,374,190,98,466,282,52,420,236,144,512,328,29,397,213,121,489,305,75, + 173,357,12,380,196,104,472,288,58,426,242,150,518,334,35,403,219,127,495,311,81,449,265, + 0,368,184,92,460,276,46,414,230,138,506,322,23,391,207,115,483,299,69,437,253,161,3 +}; + +int tableh10[] = { /* 25 x 25 data */ + 2,603,103,503,303,53,453,253,153,553,353,28,428,228,128,528,328,78,478,278,178,578,378,375,1, + 123,523,323,73,473,273,173,573,373,48,448,248,148,548,348,98,498,298,198,598,398,23,423,223,623, + 311,61,461,261,161,561,361,36,436,236,136,536,336,86,486,286,186,586,386,11,411,211,611,111,511, + 467,267,167,567,367,42,442,242,142,542,342,92,492,292,192,592,392,17,417,217,617,117,517,317,67, + 155,555,355,30,430,230,130,530,330,80,480,280,180,580,380,5,405,205,605,105,505,305,55,455,255, + 370,45,445,245,145,545,345,95,495,295,195,595,395,20,420,220,620,120,520,320,70,470,270,170,570, + 433,233,133,533,333,83,483,283,183,583,383,8,408,208,608,108,508,308,58,458,258,158,558,358,33, + 139,539,339,89,489,289,189,589,389,14,414,214,614,114,514,314,64,464,264,164,564,364,39,439,239, + 326,76,476,276,176,576,376,403,401,201,601,101,501,301,51,451,251,151,551,351,26,426,226,126,526, + 499,299,199,599,399,24,424,224,624,124,524,324,74,474,274,174,574,374,49,449,249,149,549,349,99, + 187,587,387,12,412,212,612,112,512,312,62,462,262,162,562,362,37,437,237,137,537,337,87,487,287, + 393,18,418,218,618,118,518,318,68,468,268,168,568,368,43,443,243,143,543,343,93,493,293,193,593, + 406,206,606,106,506,306,56,456,256,156,556,356,31,431,231,131,531,331,81,481,281,181,581,381,6, + 621,121,521,321,71,471,271,171,571,371,46,446,246,146,546,346,96,496,296,196,596,396,21,421,221, + 509,309,59,459,259,159,559,359,34,434,234,134,534,334,84,484,284,184,584,384,9,409,209,609,109, + 65,465,265,165,565,365,40,440,240,140,540,340,90,490,290,190,590,390,15,415,215,615,115,515,315, + 252,152,552,352,27,427,227,127,527,327,77,477,277,177,577,377,203,402,202,602,102,502,302,52,452, + 572,372,47,447,247,147,547,347,97,497,297,197,597,397,22,422,222,622,122,522,322,72,472,272,172, + 35,435,235,135,535,335,85,485,285,185,585,385,10,410,210,610,110,510,310,60,460,260,160,560,360, + 241,141,541,341,91,491,291,191,591,391,16,416,216,616,116,516,316,66,466,266,166,566,366,41,441, + 529,329,79,479,279,179,579,379,4,404,204,604,104,504,304,54,454,254,154,554,354,29,429,229,129, + 94,494,294,194,594,394,19,419,219,619,119,519,319,69,469,269,169,569,369,44,444,244,144,544,344, + 282,182,582,382,7,407,207,607,107,507,307,57,457,257,157,557,357,32,432,232,132,532,332,82,482, + 588,388,13,413,213,613,113,513,313,63,463,263,163,563,363,38,438,238,138,538,338,88,488,288,188, + 0,400,200,600,100,500,300,50,450,250,150,550,350,25,425,225,125,525,325,75,475,275,175,575,3 +}; + +int tableh11[] = { /* 27 x 27 data */ + 2,658,118,550,334,64,496,280,712,172,604,388,37,469,253,685,145,577,361,91,523,307,199,631,415,10,1, + 125,557,341,71,503,287,719,179,611,395,44,476,260,692,152,584,368,98,530,314,206,638,422,17,449,233,665, + 327,57,489,273,705,165,597,381,30,462,246,678,138,570,354,84,516,300,192,624,408,405,435,219,651,111,543, + 511,295,727,187,619,403,52,484,268,700,160,592,376,106,538,322,214,646,430,25,457,241,673,133,565,349,79, + 714,174,606,390,39,471,255,687,147,579,363,93,525,309,201,633,417,12,444,228,660,120,552,336,66,498,282, + 613,397,46,478,262,694,154,586,370,100,532,316,208,640,424,19,451,235,667,127,559,343,73,505,289,721,181, + 32,464,248,680,140,572,356,86,518,302,194,626,410,5,437,221,653,113,545,329,59,491,275,707,167,599,383, + 265,697,157,589,373,103,535,319,211,643,427,22,454,238,670,130,562,346,76,508,292,724,184,616,400,49,481, + 143,575,359,89,521,305,197,629,413,8,440,224,656,116,548,332,62,494,278,710,170,602,386,35,467,251,683, + 366,96,528,312,204,636,420,15,447,231,663,123,555,339,69,501,285,717,177,609,393,42,474,258,690,150,582, + 514,298,190,622,406,442,433,217,649,109,541,325,55,487,271,703,163,595,379,28,460,244,676,136,568,352,82, + 215,647,431,26,458,242,674,134,566,350,80,512,296,728,188,620,404,53,485,269,701,161,593,377,107,539,323, + 418,13,445,229,661,121,553,337,67,499,283,715,175,607,391,40,472,256,688,148,580,364,94,526,310,202,634, + 452,236,668,128,560,344,74,506,290,722,182,614,398,47,479,263,695,155,587,371,101,533,317,209,641,425,20, + 654,114,546,330,60,492,276,708,168,600,384,33,465,249,681,141,573,357,87,519,303,195,627,411,6,438,222, + 563,347,77,509,293,725,185,617,401,50,482,266,698,158,590,374,104,536,320,212,644,428,23,455,239,671,131, + 63,495,279,711,171,603,387,36,468,252,684,144,576,360,90,522,306,198,630,414,9,441,225,657,117,549,333, + 286,718,178,610,394,43,475,259,691,151,583,367,97,529,313,205,637,421,16,448,232,664,124,556,340,70,502, + 164,596,380,29,461,245,677,137,569,353,83,515,299,191,623,407,226,434,218,650,110,542,326,56,488,272,704, + 402,51,483,267,699,159,591,375,105,537,321,213,645,429,24,456,240,672,132,564,348,78,510,294,726,186,618, + 470,254,686,146,578,362,92,524,308,200,632,416,11,443,227,659,119,551,335,65,497,281,713,173,605,389,38, + 693,153,585,369,99,531,315,207,639,423,18,450,234,666,126,558,342,72,504,288,720,180,612,396,45,477,261, + 571,355,85,517,301,193,625,409,4,436,220,652,112,544,328,58,490,274,706,166,598,382,31,463,247,679,139, + 102,534,318,210,642,426,21,453,237,669,129,561,345,75,507,291,723,183,615,399,48,480,264,696,156,588,372, + 304,196,628,412,7,439,223,655,115,547,331,61,493,277,709,169,601,385,34,466,250,682,142,574,358,88,520, + 635,419,14,446,230,662,122,554,338,68,500,284,716,176,608,392,41,473,257,689,149,581,365,95,527,311,203, + 0,432,216,648,108,540,324,54,486,270,702,162,594,378,27,459,243,675,135,567,351,81,513,297,189,621,3 +}; + +int tableh12[] = { /* 29 x 29 data */ + 2,703,123,587,355,819,65,529,297,761,181,645,413,36,500,268,732,152,616,384,94,558,326,790,210,674,442,7,1, + 141,605,373,837,83,547,315,779,199,663,431,54,518,286,750,170,634,402,112,576,344,808,228,692,460,25,489,257,721, + 359,823,69,533,301,765,185,649,417,40,504,272,736,156,620,388,98,562,330,794,214,678,446,11,475,243,707,127,591, + 76,540,308,772,192,656,424,47,511,279,743,163,627,395,105,569,337,801,221,685,453,18,482,250,714,134,598,366,830, + 293,757,177,641,409,32,496,264,728,148,612,380,90,554,322,786,206,670,438,435,467,235,699,119,583,351,815,61,525, + 201,665,433,56,520,288,752,172,636,404,114,578,346,810,230,694,462,27,491,259,723,143,607,375,839,85,549,317,781, + 419,42,506,274,738,158,622,390,100,564,332,796,216,680,448,13,477,245,709,129,593,361,825,71,535,303,767,187,651, + 513,281,745,165,629,397,107,571,339,803,223,687,455,20,484,252,716,136,600,368,832,78,542,310,774,194,658,426,49, + 730,150,614,382,92,556,324,788,208,672,440,5,469,237,701,121,585,353,817,63,527,295,759,179,643,411,34,498,266, + 632,400,110,574,342,806,226,690,458,23,487,255,719,139,603,371,835,81,545,313,777,197,661,429,52,516,284,748,168, + 96,560,328,792,212,676,444,9,473,241,705,125,589,357,821,67,531,299,763,183,647,415,38,502,270,734,154,618,386, + 335,799,219,683,451,16,480,248,712,132,596,364,828,74,538,306,770,190,654,422,45,509,277,741,161,625,393,103,567, + 204,668,436,471,465,233,697,117,581,349,813,59,523,291,755,175,639,407,30,494,262,726,146,610,378,88,552,320,784, + 463,28,492,260,724,144,608,376,840,86,550,318,782,202,666,434,57,521,289,753,173,637,405,115,579,347,811,231,695, + 478,246,710,130,594,362,826,72,536,304,768,188,652,420,43,507,275,739,159,623,391,101,565,333,797,217,681,449,14, + 717,137,601,369,833,79,543,311,775,195,659,427,50,514,282,746,166,630,398,108,572,340,804,224,688,456,21,485,253, + 586,354,818,64,528,296,760,180,644,412,35,499,267,731,151,615,383,93,557,325,789,209,673,441,6,470,238,702,122, + 836,82,546,314,778,198,662,430,53,517,285,749,169,633,401,111,575,343,807,227,691,459,24,488,256,720,140,604,372, + 532,300,764,184,648,416,39,503,271,735,155,619,387,97,561,329,793,213,677,445,10,474,242,706,126,590,358,822,68, + 771,191,655,423,46,510,278,742,162,626,394,104,568,336,800,220,684,452,17,481,249,713,133,597,365,829,75,539,307, + 640,408,31,495,263,727,147,611,379,89,553,321,785,205,669,437,239,466,234,698,118,582,350,814,60,524,292,756,176, + 55,519,287,751,171,635,403,113,577,345,809,229,693,461,26,490,258,722,142,606,374,838,84,548,316,780,200,664,432, + 273,737,157,621,389,99,563,331,795,215,679,447,12,476,244,708,128,592,360,824,70,534,302,766,186,650,418,41,505, + 164,628,396,106,570,338,802,222,686,454,19,483,251,715,135,599,367,831,77,541,309,773,193,657,425,48,512,280,744, + 381,91,555,323,787,207,671,439,4,468,236,700,120,584,352,816,62,526,294,758,178,642,410,33,497,265,729,149,613, + 573,341,805,225,689,457,22,486,254,718,138,602,370,834,80,544,312,776,196,660,428,51,515,283,747,167,631,399,109, + 791,211,675,443,8,472,240,704,124,588,356,820,66,530,298,762,182,646,414,37,501,269,733,153,617,385,95,559,327, + 682,450,15,479,247,711,131,595,363,827,73,537,305,769,189,653,421,44,508,276,740,160,624,392,102,566,334,798,218, + 0,464,232,696,116,580,348,812,58,522,290,754,174,638,406,29,493,261,725,145,609,377,87,551,319,783,203,667,3 +}; + +int tableh13[] = { /* 31 x 31 data */ + 2,759,139,635,387,883,77,573,325,821,201,697,449,945,46,542,294,790,170,666,418,914,108,604,356,852,232,728,480,15,1, + 147,643,395,891,85,581,333,829,209,705,457,953,54,550,302,798,178,674,426,922,116,612,364,860,240,736,488,23,519,271,767, + 379,875,69,565,317,813,193,689,441,937,38,534,286,782,162,658,410,906,100,596,348,844,224,720,472,7,503,255,751,131,627, + 89,585,337,833,213,709,461,957,58,554,306,802,182,678,430,926,120,616,368,864,244,740,492,27,523,275,771,151,647,399,895, + 321,817,197,693,445,941,42,538,290,786,166,662,414,910,104,600,352,848,228,724,476,11,507,259,755,135,631,383,879,73,569, + 205,701,453,949,50,546,298,794,174,670,422,918,112,608,360,856,236,732,484,19,515,267,763,143,639,391,887,81,577,329,825, + 437,933,34,530,282,778,158,654,406,902,96,592,344,840,220,716,468,465,499,251,747,127,623,375,871,65,561,313,809,189,685, + 60,556,308,804,184,680,432,928,122,618,370,866,246,742,494,29,525,277,773,153,649,401,897,91,587,339,835,215,711,463,959, + 292,788,168,664,416,912,106,602,354,850,230,726,478,13,509,261,757,137,633,385,881,75,571,323,819,199,695,447,943,44,540, + 176,672,424,920,114,610,362,858,238,734,486,21,517,269,765,145,641,393,889,83,579,331,827,207,703,455,951,52,548,300,796, + 408,904,98,594,346,842,222,718,470,5,501,253,749,129,625,377,873,67,563,315,811,191,687,439,935,36,532,284,780,160,656, + 118,614,366,862,242,738,490,25,521,273,769,149,645,397,893,87,583,335,831,211,707,459,955,56,552,304,800,180,676,428,924, + 350,846,226,722,474,9,505,257,753,133,629,381,877,71,567,319,815,195,691,443,939,40,536,288,784,164,660,412,908,102,598, + 234,730,482,17,513,265,761,141,637,389,885,79,575,327,823,203,699,451,947,48,544,296,792,172,668,420,916,110,606,358,854, + 466,511,497,249,745,125,621,373,869,63,559,311,807,187,683,435,931,32,528,280,776,156,652,404,900,94,590,342,838,218,714, + 526,278,774,154,650,402,898,92,588,340,836,216,712,464,960,61,557,309,805,185,681,433,929,123,619,371,867,247,743,495,30, + 758,138,634,386,882,76,572,324,820,200,696,448,944,45,541,293,789,169,665,417,913,107,603,355,851,231,727,479,14,510,262, + 642,394,890,84,580,332,828,208,704,456,952,53,549,301,797,177,673,425,921,115,611,363,859,239,735,487,22,518,270,766,146, + 874,68,564,316,812,192,688,440,936,37,533,285,781,161,657,409,905,99,595,347,843,223,719,471,6,502,254,750,130,626,378, + 584,336,832,212,708,460,956,57,553,305,801,181,677,429,925,119,615,367,863,243,739,491,26,522,274,770,150,646,398,894,88, + 816,196,692,444,940,41,537,289,785,165,661,413,909,103,599,351,847,227,723,475,10,506,258,754,134,630,382,878,72,568,320, + 700,452,948,49,545,297,793,173,669,421,917,111,607,359,855,235,731,483,18,514,266,762,142,638,390,886,80,576,328,824,204, + 932,33,529,281,777,157,653,405,901,95,591,343,839,219,715,467,263,498,250,746,126,622,374,870,64,560,312,808,188,684,436, + 555,307,803,183,679,431,927,121,617,369,865,245,741,493,28,524,276,772,152,648,400,896,90,586,338,834,214,710,462,958,59, + 787,167,663,415,911,105,601,353,849,229,725,477,12,508,260,756,136,632,384,880,74,570,322,818,198,694,446,942,43,539,291, + 671,423,919,113,609,361,857,237,733,485,20,516,268,764,144,640,392,888,82,578,330,826,206,702,454,950,51,547,299,795,175, + 903,97,593,345,841,221,717,469,4,500,252,748,128,624,376,872,66,562,314,810,190,686,438,934,35,531,283,779,159,655,407, + 613,365,861,241,737,489,24,520,272,768,148,644,396,892,86,582,334,830,210,706,458,954,55,551,303,799,179,675,427,923,117, + 845,225,721,473,8,504,256,752,132,628,380,876,70,566,318,814,194,690,442,938,39,535,287,783,163,659,411,907,101,597,349, + 729,481,16,512,264,760,140,636,388,884,78,574,326,822,202,698,450,946,47,543,295,791,171,667,419,915,109,605,357,853,233, + 0,496,248,744,124,620,372,868,62,558,310,806,186,682,434,930,31,527,279,775,155,651,403,899,93,589,341,837,217,713,3 +}; + +int tableh14[] = { /* 33 x 33 data */ + 2,265,793,133,661,397,925,67,595,331,859,199,727,463,991,34,562,298,826,166,694,430,958,100,628,364,892,232,760,496,1024,1057,1, + 824,164,692,428,956,98,626,362,890,230,758,494,1022,65,593,329,857,197,725,461,989,131,659,395,923,263,791,527,1055,32,1088,560,296, + 676,412,940,82,610,346,874,214,742,478,1006,49,577,313,841,181,709,445,973,115,643,379,907,247,775,511,1039,16,1072,544,280,808,148, + 948,90,618,354,882,222,750,486,1014,57,585,321,849,189,717,453,981,123,651,387,915,255,783,519,1047,24,1080,552,288,816,156,684,420, + 602,338,866,206,734,470,998,41,569,305,833,173,701,437,965,107,635,371,899,239,767,503,1031,8,1064,536,272,800,140,668,404,932,74, + 886,226,754,490,1018,61,589,325,853,193,721,457,985,127,655,391,919,259,787,523,1051,28,1084,556,292,820,160,688,424,952,94,622,358, + 738,474,1002,45,573,309,837,177,705,441,969,111,639,375,903,243,771,507,1035,12,1068,540,276,804,144,672,408,936,78,606,342,870,210, + 1010,53,581,317,845,185,713,449,977,119,647,383,911,251,779,515,1043,20,1076,548,284,812,152,680,416,944,86,614,350,878,218,746,482, + 565,301,829,169,697,433,961,103,631,367,895,235,763,499,1027,4,1060,532,268,796,136,664,400,928,70,598,334,862,202,730,466,994,37, + 855,195,723,459,987,129,657,393,921,261,789,525,1053,30,1086,558,294,822,162,690,426,954,96,624,360,888,228,756,492,1020,63,591,327, + 707,443,971,113,641,377,905,245,773,509,1037,14,1070,542,278,806,146,674,410,938,80,608,344,872,212,740,476,1004,47,575,311,839,179, + 979,121,649,385,913,253,781,517,1045,22,1078,550,286,814,154,682,418,946,88,616,352,880,220,748,484,1012,55,583,319,847,187,715,451, + 633,369,897,237,765,501,1029,6,1062,534,270,798,138,666,402,930,72,600,336,864,204,732,468,996,39,567,303,831,171,699,435,963,105, + 917,257,785,521,1049,26,1082,554,290,818,158,686,422,950,92,620,356,884,224,752,488,1016,59,587,323,851,191,719,455,983,125,653,389, + 769,505,1033,10,1066,538,274,802,142,670,406,934,76,604,340,868,208,736,472,1000,43,571,307,835,175,703,439,967,109,637,373,901,241, + 1041,18,1074,546,282,810,150,678,414,942,84,612,348,876,216,744,480,1008,51,579,315,843,183,711,447,975,117,645,381,909,249,777,513, + 1058,530,266,794,134,662,398,926,68,596,332,860,200,728,464,992,35,563,299,827,167,695,431,959,101,629,365,893,233,761,497,1025,529, + 295,823,163,691,427,955,97,625,361,889,229,757,493,1021,64,592,328,856,196,724,460,988,130,658,394,922,262,790,526,1054,31,1087,559, + 147,675,411,939,81,609,345,873,213,741,477,1005,48,576,312,840,180,708,444,972,114,642,378,906,246,774,510,1038,15,1071,543,279,807, + 419,947,89,617,353,881,221,749,485,1013,56,584,320,848,188,716,452,980,122,650,386,914,254,782,518,1046,23,1079,551,287,815,155,683, + 73,601,337,865,205,733,469,997,40,568,304,832,172,700,436,964,106,634,370,898,238,766,502,1030,7,1063,535,271,799,139,667,403,931, + 357,885,225,753,489,1017,60,588,324,852,192,720,456,984,126,654,390,918,258,786,522,1050,27,1083,555,291,819,159,687,423,951,93,621, + 209,737,473,1001,44,572,308,836,176,704,440,968,110,638,374,902,242,770,506,1034,11,1067,539,275,803,143,671,407,935,77,605,341,869, + 481,1009,52,580,316,844,184,712,448,976,118,646,382,910,250,778,514,1042,19,1075,547,283,811,151,679,415,943,85,613,349,877,217,745, + 36,564,300,828,168,696,432,960,102,630,366,894,234,762,498,1026,1023,1059,531,267,795,135,663,399,927,69,597,333,861,201,729,465,993, + 326,854,194,722,458,986,128,656,392,920,260,788,524,1052,29,1085,557,293,821,161,689,425,953,95,623,359,887,227,755,491,1019,62,590, + 178,706,442,970,112,640,376,904,244,772,508,1036,13,1069,541,277,805,145,673,409,937,79,607,343,871,211,739,475,1003,46,574,310,838, + 450,978,120,648,384,912,252,780,516,1044,21,1077,549,285,813,153,681,417,945,87,615,351,879,219,747,483,1011,54,582,318,846,186,714, + 104,632,368,896,236,764,500,1028,5,1061,533,269,797,137,665,401,929,71,599,335,863,203,731,467,995,38,566,302,830,170,698,434,962, + 388,916,256,784,520,1048,25,1081,553,289,817,157,685,421,949,91,619,355,883,223,751,487,1015,58,586,322,850,190,718,454,982,124,652, + 240,768,504,1032,9,1065,537,273,801,141,669,405,933,75,603,339,867,207,735,471,999,42,570,306,834,174,702,438,966,108,636,372,900, + 512,1040,17,1073,545,281,809,149,677,413,941,83,611,347,875,215,743,479,1007,50,578,314,842,182,710,446,974,116,644,380,908,248,776, + 0,1056,528,264,792,132,660,396,924,66,594,330,858,198,726,462,990,33,561,297,825,165,693,429,957,99,627,363,891,231,759,495,3 +}; + +int tableh15[] = { /* 35 x 35 data */ + 2,290,850,150,710,430,990,80,1200,640,360,920,220,780,500,1060,45,1165,605,325,885,185,745,465,1025,115,675,395,955,255,815,535,1095,10,1, + 859,159,719,439,999,89,1209,649,369,929,229,789,509,1069,54,1174,614,334,894,194,754,474,1034,124,684,404,964,264,824,544,1104,19,1139,579,299, + 701,421,981,71,1191,631,351,911,211,771,491,1051,36,1156,596,316,876,176,736,456,1016,106,666,386,946,246,806,526,1086,1130,1121,561,281,841,141, + 1014,104,1224,664,384,944,244,804,524,1084,69,1189,629,349,909,209,769,489,1049,139,699,419,979,279,839,559,1119,34,1154,594,314,874,174,734,454, + 1207,647,367,927,227,787,507,1067,52,1172,612,332,892,192,752,472,1032,122,682,402,962,262,822,542,1102,17,1137,577,297,857,157,717,437,997,87, + 376,936,236,796,516,1076,61,1181,621,341,901,201,761,481,1041,131,691,411,971,271,831,551,1111,26,1146,586,306,866,166,726,446,1006,96,1216,656, + 218,778,498,1058,43,1163,603,323,883,183,743,463,1023,113,673,393,953,253,813,533,1093,8,1128,568,288,848,148,708,428,988,78,1198,638,358,918, + 520,1080,65,1185,625,345,905,205,765,485,1045,135,695,415,975,275,835,555,1115,30,1150,590,310,870,170,730,450,1010,100,1220,660,380,940,240,800, + 48,1168,608,328,888,188,748,468,1028,118,678,398,958,258,818,538,1098,13,1133,573,293,853,153,713,433,993,83,1203,643,363,923,223,783,503,1063, + 617,337,897,197,757,477,1037,127,687,407,967,267,827,547,1107,22,1142,582,302,862,162,722,442,1002,92,1212,652,372,932,232,792,512,1072,57,1177, + 879,179,739,459,1019,109,669,389,949,249,809,529,1089,4,1124,564,284,844,144,704,424,984,74,1194,634,354,914,214,774,494,1054,39,1159,599,319, + 767,487,1047,137,697,417,977,277,837,557,1117,32,1152,592,312,872,172,732,452,1012,102,1222,662,382,942,242,802,522,1082,67,1187,627,347,907,207, + 1030,120,680,400,960,260,820,540,1100,15,1135,575,295,855,155,715,435,995,85,1205,645,365,925,225,785,505,1065,50,1170,610,330,890,190,750,470, + 689,409,969,269,829,549,1109,24,1144,584,304,864,164,724,444,1004,94,1214,654,374,934,234,794,514,1074,59,1179,619,339,899,199,759,479,1039,129, + 951,251,811,531,1091,6,1126,566,286,846,146,706,426,986,76,1196,636,356,916,216,776,496,1056,41,1161,601,321,881,181,741,461,1021,111,671,391, + 833,553,1113,28,1148,588,308,868,168,728,448,1008,98,1218,658,378,938,238,798,518,1078,63,1183,623,343,903,203,763,483,1043,133,693,413,973,273, + 1096,11,1131,571,291,851,151,711,431,991,81,1201,641,361,921,221,781,501,1061,46,1166,606,326,886,186,746,466,1026,116,676,396,956,256,816,536, + 1140,580,300,860,160,720,440,1000,90,1210,650,370,930,230,790,510,1070,55,1175,615,335,895,195,755,475,1035,125,685,405,965,265,825,545,1105,20, + 282,842,142,702,422,982,72,1192,632,352,912,212,772,492,1052,37,1157,597,317,877,177,737,457,1017,107,667,387,947,247,807,527,1087,570,1122,562, + 173,733,453,1013,103,1223,663,383,943,243,803,523,1083,68,1188,628,348,908,208,768,488,1048,138,698,418,978,278,838,558,1118,33,1153,593,313,873, + 436,996,86,1206,646,366,926,226,786,506,1066,51,1171,611,331,891,191,751,471,1031,121,681,401,961,261,821,541,1101,16,1136,576,296,856,156,716, + 95,1215,655,375,935,235,795,515,1075,60,1180,620,340,900,200,760,480,1040,130,690,410,970,270,830,550,1110,25,1145,585,305,865,165,725,445,1005, + 637,357,917,217,777,497,1057,42,1162,602,322,882,182,742,462,1022,112,672,392,952,252,812,532,1092,7,1127,567,287,847,147,707,427,987,77,1197, + 939,239,799,519,1079,64,1184,624,344,904,204,764,484,1044,134,694,414,974,274,834,554,1114,29,1149,589,309,869,169,729,449,1009,99,1219,659,379, + 782,502,1062,47,1167,607,327,887,187,747,467,1027,117,677,397,957,257,817,537,1097,12,1132,572,292,852,152,712,432,992,82,1202,642,362,922,222, + 1071,56,1176,616,336,896,196,756,476,1036,126,686,406,966,266,826,546,1106,21,1141,581,301,861,161,721,441,1001,91,1211,651,371,931,231,791,511, + 1158,598,318,878,178,738,458,1018,108,668,388,948,248,808,528,1088,1085,1123,563,283,843,143,703,423,983,73,1193,633,353,913,213,773,493,1053,38, + 346,906,206,766,486,1046,136,696,416,976,276,836,556,1116,31,1151,591,311,871,171,731,451,1011,101,1221,661,381,941,241,801,521,1081,66,1186,626, + 189,749,469,1029,119,679,399,959,259,819,539,1099,14,1134,574,294,854,154,714,434,994,84,1204,644,364,924,224,784,504,1064,49,1169,609,329,889, + 478,1038,128,688,408,968,268,828,548,1108,23,1143,583,303,863,163,723,443,1003,93,1213,653,373,933,233,793,513,1073,58,1178,618,338,898,198,758, + 110,670,390,950,250,810,530,1090,5,1125,565,285,845,145,705,425,985,75,1195,635,355,915,215,775,495,1055,40,1160,600,320,880,180,740,460,1020, + 412,972,272,832,552,1112,27,1147,587,307,867,167,727,447,1007,97,1217,657,377,937,237,797,517,1077,62,1182,622,342,902,202,762,482,1042,132,692, + 254,814,534,1094,9,1129,569,289,849,149,709,429,989,79,1199,639,359,919,219,779,499,1059,44,1164,604,324,884,184,744,464,1024,114,674,394,954, + 543,1103,18,1138,578,298,858,158,718,438,998,88,1208,648,368,928,228,788,508,1068,53,1173,613,333,893,193,753,473,1033,123,683,403,963,263,823, + 0,1120,560,280,840,140,700,420,980,70,1190,630,350,910,210,770,490,1050,35,1155,595,315,875,175,735,455,1015,105,665,385,945,245,805,525,3 +}; + +int tableh16[] = { /* 37 x 37 data */ + 2,302,894,154,1338,746,450,1042,80,1264,672,376,968,228,820,524,1116,43,1227,635,339,931,191,783,487,1079,117,1301,709,413,1005,265,857,561,1153,6,1, + 917,177,1361,769,473,1065,103,1287,695,399,991,251,843,547,1139,66,1250,658,362,954,214,806,510,1102,140,1324,732,436,1028,288,880,584,1176,29,1213,621,325, + 1343,751,455,1047,85,1269,677,381,973,233,825,529,1121,48,1232,640,344,936,196,788,492,1084,122,1306,714,418,1010,270,862,566,1158,11,1195,603,307,899,159, + 464,1056,94,1278,686,390,982,242,834,538,1130,57,1241,649,353,945,205,797,501,1093,131,1315,723,427,1019,279,871,575,1167,20,1204,612,316,908,168,1352,760, + 75,1259,667,371,963,223,815,519,1111,38,1222,630,334,926,186,778,482,1074,112,1296,704,408,1000,260,852,556,1148,1190,1185,593,297,889,149,1333,741,445,1037, + 702,406,998,258,850,554,1146,73,1257,665,369,961,221,813,517,1109,147,1331,739,443,1035,295,887,591,1183,36,1220,628,332,924,184,1368,776,480,1072,110,1294, + 980,240,832,536,1128,55,1239,647,351,943,203,795,499,1091,129,1313,721,425,1017,277,869,573,1165,18,1202,610,314,906,166,1350,758,462,1054,92,1276,684,388, + 841,545,1137,64,1248,656,360,952,212,804,508,1100,138,1322,730,434,1026,286,878,582,1174,27,1211,619,323,915,175,1359,767,471,1063,101,1285,693,397,989,249, + 1119,46,1230,638,342,934,194,786,490,1082,120,1304,712,416,1008,268,860,564,1156,9,1193,601,305,897,157,1341,749,453,1045,83,1267,675,379,971,231,823,527, + 1253,661,365,957,217,809,513,1105,143,1327,735,439,1031,291,883,587,1179,32,1216,624,328,920,180,1364,772,476,1068,106,1290,698,402,994,254,846,550,1142,69, + 347,939,199,791,495,1087,125,1309,717,421,1013,273,865,569,1161,14,1198,606,310,902,162,1346,754,458,1050,88,1272,680,384,976,236,828,532,1124,51,1235,643, + 208,800,504,1096,134,1318,726,430,1022,282,874,578,1170,23,1207,615,319,911,171,1355,763,467,1059,97,1281,689,393,985,245,837,541,1133,60,1244,652,356,948, + 485,1077,115,1299,707,411,1003,263,855,559,1151,4,1188,596,300,892,152,1336,744,448,1040,78,1262,670,374,966,226,818,522,1114,41,1225,633,337,929,189,781, + 145,1329,737,441,1033,293,885,589,1181,34,1218,626,330,922,182,1366,774,478,1070,108,1292,700,404,996,256,848,552,1144,71,1255,663,367,959,219,811,515,1107, + 719,423,1015,275,867,571,1163,16,1200,608,312,904,164,1348,756,460,1052,90,1274,682,386,978,238,830,534,1126,53,1237,645,349,941,201,793,497,1089,127,1311, + 1024,284,876,580,1172,25,1209,617,321,913,173,1357,765,469,1061,99,1283,691,395,987,247,839,543,1135,62,1246,654,358,950,210,802,506,1098,136,1320,728,432, + 858,562,1154,7,1191,599,303,895,155,1339,747,451,1043,81,1265,673,377,969,229,821,525,1117,44,1228,636,340,932,192,784,488,1080,118,1302,710,414,1006,266, + 1177,30,1214,622,326,918,178,1362,770,474,1066,104,1288,696,400,992,252,844,548,1140,67,1251,659,363,955,215,807,511,1103,141,1325,733,437,1029,289,881,585, + 1196,604,308,900,160,1344,752,456,1048,86,1270,678,382,974,234,826,530,1122,49,1233,641,345,937,197,789,493,1085,123,1307,715,419,1011,271,863,567,1159,12, + 317,909,169,1353,761,465,1057,95,1279,687,391,983,243,835,539,1131,58,1242,650,354,946,206,798,502,1094,132,1316,724,428,1020,280,872,576,1168,21,1205,613, + 150,1334,742,446,1038,76,1260,668,372,964,224,816,520,1112,39,1223,631,335,927,187,779,483,1075,113,1297,705,409,1001,261,853,557,1149,598,1186,594,298,890, + 775,479,1071,109,1293,701,405,997,257,849,553,1145,72,1256,664,368,960,220,812,516,1108,146,1330,738,442,1034,294,886,590,1182,35,1219,627,331,923,183,1367, + 1053,91,1275,683,387,979,239,831,535,1127,54,1238,646,350,942,202,794,498,1090,128,1312,720,424,1016,276,868,572,1164,17,1201,609,313,905,165,1349,757,461, + 1284,692,396,988,248,840,544,1136,63,1247,655,359,951,211,803,507,1099,137,1321,729,433,1025,285,877,581,1173,26,1210,618,322,914,174,1358,766,470,1062,100, + 378,970,230,822,526,1118,45,1229,637,341,933,193,785,489,1081,119,1303,711,415,1007,267,859,563,1155,8,1192,600,304,896,156,1340,748,452,1044,82,1266,674, + 253,845,549,1141,68,1252,660,364,956,216,808,512,1104,142,1326,734,438,1030,290,882,586,1178,31,1215,623,327,919,179,1363,771,475,1067,105,1289,697,401,993, + 531,1123,50,1234,642,346,938,198,790,494,1086,124,1308,716,420,1012,272,864,568,1160,13,1197,605,309,901,161,1345,753,457,1049,87,1271,679,383,975,235,827, + 59,1243,651,355,947,207,799,503,1095,133,1317,725,429,1021,281,873,577,1169,22,1206,614,318,910,170,1354,762,466,1058,96,1280,688,392,984,244,836,540,1132, + 632,336,928,188,780,484,1076,114,1298,706,410,1002,262,854,558,1150,1147,1187,595,299,891,151,1335,743,447,1039,77,1261,669,373,965,225,817,521,1113,40,1224, + 958,218,810,514,1106,144,1328,736,440,1032,292,884,588,1180,33,1217,625,329,921,181,1365,773,477,1069,107,1291,699,403,995,255,847,551,1143,70,1254,662,366, + 792,496,1088,126,1310,718,422,1014,274,866,570,1162,15,1199,607,311,903,163,1347,755,459,1051,89,1273,681,385,977,237,829,533,1125,52,1236,644,348,940,200, + 1097,135,1319,727,431,1023,283,875,579,1171,24,1208,616,320,912,172,1356,764,468,1060,98,1282,690,394,986,246,838,542,1134,61,1245,653,357,949,209,801,505, + 1300,708,412,1004,264,856,560,1152,5,1189,597,301,893,153,1337,745,449,1041,79,1263,671,375,967,227,819,523,1115,42,1226,634,338,930,190,782,486,1078,116, + 435,1027,287,879,583,1175,28,1212,620,324,916,176,1360,768,472,1064,102,1286,694,398,990,250,842,546,1138,65,1249,657,361,953,213,805,509,1101,139,1323,731, + 269,861,565,1157,10,1194,602,306,898,158,1342,750,454,1046,84,1268,676,380,972,232,824,528,1120,47,1231,639,343,935,195,787,491,1083,121,1305,713,417,1009, + 574,1166,19,1203,611,315,907,167,1351,759,463,1055,93,1277,685,389,981,241,833,537,1129,56,1240,648,352,944,204,796,500,1092,130,1314,722,426,1018,278,870, + 0,1184,592,296,888,148,1332,740,444,1036,74,1258,666,370,962,222,814,518,1110,37,1221,629,333,925,185,777,481,1073,111,1295,703,407,999,259,851,555,3 +}; + +int tableh17[] = { /* 39 x 39 data */ + 2,328,952,172,1420,796,484,1108,94,1342,718,406,1030,250,1498,874,562,1186,55,1303,679,367,991,211,1459,835,523,1147,133,1381,757,445,1069,289,913,601,1225,16,1, + 962,182,1430,806,494,1118,104,1352,728,416,1040,260,1508,884,572,1196,65,1313,689,377,1001,221,1469,845,533,1157,143,1391,767,455,1079,299,923,611,1235,26,1274,650,338, + 1410,786,474,1098,84,1332,708,396,1020,240,1488,864,552,1176,45,1293,669,357,981,201,1449,825,513,1137,123,1371,747,435,1059,279,903,591,1215,6,1254,630,318,942,162, + 499,1123,109,1357,733,421,1045,265,1513,889,577,1201,70,1318,694,382,1006,226,1474,850,538,1162,148,1396,772,460,1084,304,928,616,1240,31,1279,655,343,967,187,1435,811, + 89,1337,713,401,1025,245,1493,869,557,1181,50,1298,674,362,986,206,1454,830,518,1142,128,1376,752,440,1064,284,908,596,1220,11,1259,635,323,947,167,1415,791,479,1103, + 723,411,1035,255,1503,879,567,1191,60,1308,684,372,996,216,1464,840,528,1152,138,1386,762,450,1074,294,918,606,1230,21,1269,645,333,957,177,1425,801,489,1113,99,1347, + 1015,235,1483,859,547,1171,40,1288,664,352,976,196,1444,820,508,1132,118,1366,742,430,1054,274,898,586,1210,1264,1249,625,313,937,157,1405,781,469,1093,79,1327,703,391, + 1520,896,584,1208,77,1325,701,389,1013,233,1481,857,545,1169,155,1403,779,467,1091,311,935,623,1247,38,1286,662,350,974,194,1442,818,506,1130,116,1364,740,428,1052,272, + 565,1189,58,1306,682,370,994,214,1462,838,526,1150,136,1384,760,448,1072,292,916,604,1228,19,1267,643,331,955,175,1423,799,487,1111,97,1345,721,409,1033,253,1501,877, + 68,1316,692,380,1004,224,1472,848,536,1160,146,1394,770,458,1082,302,926,614,1238,29,1277,653,341,965,185,1433,809,497,1121,107,1355,731,419,1043,263,1511,887,575,1199, + 672,360,984,204,1452,828,516,1140,126,1374,750,438,1062,282,906,594,1218,9,1257,633,321,945,165,1413,789,477,1101,87,1335,711,399,1023,243,1491,867,555,1179,48,1296, + 1009,229,1477,853,541,1165,151,1399,775,463,1087,307,931,619,1243,34,1282,658,346,970,190,1438,814,502,1126,112,1360,736,424,1048,268,1516,892,580,1204,73,1321,697,385, + 1457,833,521,1145,131,1379,755,443,1067,287,911,599,1223,14,1262,638,326,950,170,1418,794,482,1106,92,1340,716,404,1028,248,1496,872,560,1184,53,1301,677,365,989,209, + 531,1155,141,1389,765,453,1077,297,921,609,1233,24,1272,648,336,960,180,1428,804,492,1116,102,1350,726,414,1038,258,1506,882,570,1194,63,1311,687,375,999,219,1467,843, + 121,1369,745,433,1057,277,901,589,1213,4,1252,628,316,940,160,1408,784,472,1096,82,1330,706,394,1018,238,1486,862,550,1174,43,1291,667,355,979,199,1447,823,511,1135, + 777,465,1089,309,933,621,1245,36,1284,660,348,972,192,1440,816,504,1128,114,1362,738,426,1050,270,1518,894,582,1206,75,1323,699,387,1011,231,1479,855,543,1167,153,1401, + 1070,290,914,602,1226,17,1265,641,329,953,173,1421,797,485,1109,95,1343,719,407,1031,251,1499,875,563,1187,56,1304,680,368,992,212,1460,836,524,1148,134,1382,758,446, + 924,612,1236,27,1275,651,339,963,183,1431,807,495,1119,105,1353,729,417,1041,261,1509,885,573,1197,66,1314,690,378,1002,222,1470,846,534,1158,144,1392,768,456,1080,300, + 1216,7,1255,631,319,943,163,1411,787,475,1099,85,1333,709,397,1021,241,1489,865,553,1177,46,1294,670,358,982,202,1450,826,514,1138,124,1372,748,436,1060,280,904,592, + 1280,656,344,968,188,1436,812,500,1124,110,1358,734,422,1046,266,1514,890,578,1202,71,1319,695,383,1007,227,1475,851,539,1163,149,1397,773,461,1085,305,929,617,1241,32, + 324,948,168,1416,792,480,1104,90,1338,714,402,1026,246,1494,870,558,1182,51,1299,675,363,987,207,1455,831,519,1143,129,1377,753,441,1065,285,909,597,1221,12,1260,636, + 178,1426,802,490,1114,100,1348,724,412,1036,256,1504,880,568,1192,61,1309,685,373,997,217,1465,841,529,1153,139,1387,763,451,1075,295,919,607,1231,22,1270,646,334,958, + 782,470,1094,80,1328,704,392,1016,236,1484,860,548,1172,41,1289,665,353,977,197,1445,821,509,1133,119,1367,743,431,1055,275,899,587,1211,640,1250,626,314,938,158,1406, + 1129,115,1363,739,427,1051,271,1519,895,583,1207,76,1324,700,388,1012,232,1480,856,544,1168,154,1402,778,466,1090,310,934,622,1246,37,1285,661,349,973,193,1441,817,505, + 1344,720,408,1032,252,1500,876,564,1188,57,1305,681,369,993,213,1461,837,525,1149,135,1383,759,447,1071,291,915,603,1227,18,1266,642,330,954,174,1422,798,486,1110,96, + 418,1042,262,1510,886,574,1198,67,1315,691,379,1003,223,1471,847,535,1159,145,1393,769,457,1081,301,925,613,1237,28,1276,652,340,964,184,1432,808,496,1120,106,1354,730, + 242,1490,866,554,1178,47,1295,671,359,983,203,1451,827,515,1139,125,1373,749,437,1061,281,905,593,1217,8,1256,632,320,944,164,1412,788,476,1100,86,1334,710,398,1022, + 891,579,1203,72,1320,696,384,1008,228,1476,852,540,1164,150,1398,774,462,1086,306,930,618,1242,33,1281,657,345,969,189,1437,813,501,1125,111,1359,735,423,1047,267,1515, + 1183,52,1300,676,364,988,208,1456,832,520,1144,130,1378,754,442,1066,286,910,598,1222,13,1261,637,325,949,169,1417,793,481,1105,91,1339,715,403,1027,247,1495,871,559, + 1310,686,374,998,218,1466,842,530,1154,140,1388,764,452,1076,296,920,608,1232,23,1271,647,335,959,179,1427,803,491,1115,101,1349,725,413,1037,257,1505,881,569,1193,62, + 354,978,198,1446,822,510,1134,120,1368,744,432,1056,276,900,588,1212,1209,1251,627,315,939,159,1407,783,471,1095,81,1329,705,393,1017,237,1485,861,549,1173,42,1290,666, + 230,1478,854,542,1166,152,1400,776,464,1088,308,932,620,1244,35,1283,659,347,971,191,1439,815,503,1127,113,1361,737,425,1049,269,1517,893,581,1205,74,1322,698,386,1010, + 834,522,1146,132,1380,756,444,1068,288,912,600,1224,15,1263,639,327,951,171,1419,795,483,1107,93,1341,717,405,1029,249,1497,873,561,1185,54,1302,678,366,990,210,1458, + 1156,142,1390,766,454,1078,298,922,610,1234,25,1273,649,337,961,181,1429,805,493,1117,103,1351,727,415,1039,259,1507,883,571,1195,64,1312,688,376,1000,220,1468,844,532, + 1370,746,434,1058,278,902,590,1214,5,1253,629,317,941,161,1409,785,473,1097,83,1331,707,395,1019,239,1487,863,551,1175,44,1292,668,356,980,200,1448,824,512,1136,122, + 459,1083,303,927,615,1239,30,1278,654,342,966,186,1434,810,498,1122,108,1356,732,420,1044,264,1512,888,576,1200,69,1317,693,381,1005,225,1473,849,537,1161,147,1395,771, + 283,907,595,1219,10,1258,634,322,946,166,1414,790,478,1102,88,1336,712,400,1024,244,1492,868,556,1180,49,1297,673,361,985,205,1453,829,517,1141,127,1375,751,439,1063, + 605,1229,20,1268,644,332,956,176,1424,800,488,1112,98,1346,722,410,1034,254,1502,878,566,1190,59,1307,683,371,995,215,1463,839,527,1151,137,1385,761,449,1073,293,917, + 0,1248,624,312,936,156,1404,780,468,1092,78,1326,702,390,1014,234,1482,858,546,1170,39,1287,663,351,975,195,1443,819,507,1131,117,1365,741,429,1053,273,897,585,3 +}; + +int tableh18[] = { /* 41 x 41 data */ + 2,332,1644,988,168,1480,824,496,1152,86,1398,742,414,1070,250,1562,906,578,1234,45,1357,701,373,1029,209,1521,865,537,1193,127,1439,783,455,1111,291,1603,947,619,1275,4,1, + 1677,1021,201,1513,857,529,1185,119,1431,775,447,1103,283,1595,939,611,1267,78,1390,734,406,1062,242,1554,898,570,1226,160,1472,816,488,1144,324,1636,980,652,1308,37,1349,693,365, + 181,1493,837,509,1165,99,1411,755,427,1083,263,1575,919,591,1247,58,1370,714,386,1042,222,1534,878,550,1206,140,1452,796,468,1124,304,1616,960,632,1288,17,1329,673,345,1657,1001, + 847,519,1175,109,1421,765,437,1093,273,1585,929,601,1257,68,1380,724,396,1052,232,1544,888,560,1216,150,1462,806,478,1134,314,1626,970,642,1298,27,1339,683,355,1667,1011,191,1503, + 1155,89,1401,745,417,1073,253,1565,909,581,1237,48,1360,704,376,1032,212,1524,868,540,1196,130,1442,786,458,1114,294,1606,950,622,1278,7,1319,663,335,1647,991,171,1483,827,499, + 1426,770,442,1098,278,1590,934,606,1262,73,1385,729,401,1057,237,1549,893,565,1221,155,1467,811,483,1139,319,1631,975,647,1303,32,1344,688,360,1672,1016,196,1508,852,524,1180,114, + 422,1078,258,1570,914,586,1242,53,1365,709,381,1037,217,1529,873,545,1201,135,1447,791,463,1119,299,1611,955,627,1283,12,1324,668,340,1652,996,176,1488,832,504,1160,94,1406,750, + 268,1580,924,596,1252,63,1375,719,391,1047,227,1539,883,555,1211,145,1457,801,473,1129,309,1621,965,637,1293,22,1334,678,350,1662,1006,186,1498,842,514,1170,104,1416,760,432,1088, + 903,575,1231,42,1354,698,370,1026,206,1518,862,534,1190,124,1436,780,452,1108,288,1600,944,616,1272,1316,1313,657,329,1641,985,165,1477,821,493,1149,83,1395,739,411,1067,247,1559, + 1270,81,1393,737,409,1065,245,1557,901,573,1229,163,1475,819,491,1147,327,1639,983,655,1311,40,1352,696,368,1680,1024,204,1516,860,532,1188,122,1434,778,450,1106,286,1598,942,614, + 1373,717,389,1045,225,1537,881,553,1209,143,1455,799,471,1127,307,1619,963,635,1291,20,1332,676,348,1660,1004,184,1496,840,512,1168,102,1414,758,430,1086,266,1578,922,594,1250,61, + 399,1055,235,1547,891,563,1219,153,1465,809,481,1137,317,1629,973,645,1301,30,1342,686,358,1670,1014,194,1506,850,522,1178,112,1424,768,440,1096,276,1588,932,604,1260,71,1383,727, + 215,1527,871,543,1199,133,1445,789,461,1117,297,1609,953,625,1281,10,1322,666,338,1650,994,174,1486,830,502,1158,92,1404,748,420,1076,256,1568,912,584,1240,51,1363,707,379,1035, + 896,568,1224,158,1470,814,486,1142,322,1634,978,650,1306,35,1347,691,363,1675,1019,199,1511,855,527,1183,117,1429,773,445,1101,281,1593,937,609,1265,76,1388,732,404,1060,240,1552, + 1204,138,1450,794,466,1122,302,1614,958,630,1286,15,1327,671,343,1655,999,179,1491,835,507,1163,97,1409,753,425,1081,261,1573,917,589,1245,56,1368,712,384,1040,220,1532,876,548, + 1460,804,476,1132,312,1624,968,640,1296,25,1337,681,353,1665,1009,189,1501,845,517,1173,107,1419,763,435,1091,271,1583,927,599,1255,66,1378,722,394,1050,230,1542,886,558,1214,148, + 456,1112,292,1604,948,620,1276,5,1317,661,333,1645,989,169,1481,825,497,1153,87,1399,743,415,1071,251,1563,907,579,1235,46,1358,702,374,1030,210,1522,866,538,1194,128,1440,784, + 325,1637,981,653,1309,38,1350,694,366,1678,1022,202,1514,858,530,1186,120,1432,776,448,1104,284,1596,940,612,1268,79,1391,735,407,1063,243,1555,899,571,1227,161,1473,817,489,1145, + 961,633,1289,18,1330,674,346,1658,1002,182,1494,838,510,1166,100,1412,756,428,1084,264,1576,920,592,1248,59,1371,715,387,1043,223,1535,879,551,1207,141,1453,797,469,1125,305,1617, + 1299,28,1340,684,356,1668,1012,192,1504,848,520,1176,110,1422,766,438,1094,274,1586,930,602,1258,69,1381,725,397,1053,233,1545,889,561,1217,151,1463,807,479,1135,315,1627,971,643, + 1320,664,336,1648,992,172,1484,828,500,1156,90,1402,746,418,1074,254,1566,910,582,1238,49,1361,705,377,1033,213,1525,869,541,1197,131,1443,787,459,1115,295,1607,951,623,1279,8, + 361,1673,1017,197,1509,853,525,1181,115,1427,771,443,1099,279,1591,935,607,1263,74,1386,730,402,1058,238,1550,894,566,1222,156,1468,812,484,1140,320,1632,976,648,1304,33,1345,689, + 997,177,1489,833,505,1161,95,1407,751,423,1079,259,1571,915,587,1243,54,1366,710,382,1038,218,1530,874,546,1202,136,1448,792,464,1120,300,1612,956,628,1284,13,1325,669,341,1653, + 1499,843,515,1171,105,1417,761,433,1089,269,1581,925,597,1253,64,1376,720,392,1048,228,1540,884,556,1212,146,1458,802,474,1130,310,1622,966,638,1294,23,1335,679,351,1663,1007,187, + 494,1150,84,1396,740,412,1068,248,1560,904,576,1232,43,1355,699,371,1027,207,1519,863,535,1191,125,1437,781,453,1109,289,1601,945,617,1273,660,1314,658,330,1642,986,166,1478,822, + 121,1433,777,449,1105,285,1597,941,613,1269,80,1392,736,408,1064,244,1556,900,572,1228,162,1474,818,490,1146,326,1638,982,654,1310,39,1351,695,367,1679,1023,203,1515,859,531,1187, + 757,429,1085,265,1577,921,593,1249,60,1372,716,388,1044,224,1536,880,552,1208,142,1454,798,470,1126,306,1618,962,634,1290,19,1331,675,347,1659,1003,183,1495,839,511,1167,101,1413, + 1095,275,1587,931,603,1259,70,1382,726,398,1054,234,1546,890,562,1218,152,1464,808,480,1136,316,1628,972,644,1300,29,1341,685,357,1669,1013,193,1505,849,521,1177,111,1423,767,439, + 1567,911,583,1239,50,1362,706,378,1034,214,1526,870,542,1198,132,1444,788,460,1116,296,1608,952,624,1280,9,1321,665,337,1649,993,173,1485,829,501,1157,91,1403,747,419,1075,255, + 608,1264,75,1387,731,403,1059,239,1551,895,567,1223,157,1469,813,485,1141,321,1633,977,649,1305,34,1346,690,362,1674,1018,198,1510,854,526,1182,116,1428,772,444,1100,280,1592,936, + 55,1367,711,383,1039,219,1531,875,547,1203,137,1449,793,465,1121,301,1613,957,629,1285,14,1326,670,342,1654,998,178,1490,834,506,1162,96,1408,752,424,1080,260,1572,916,588,1244, + 721,393,1049,229,1541,885,557,1213,147,1459,803,475,1131,311,1623,967,639,1295,24,1336,680,352,1664,1008,188,1500,844,516,1172,106,1418,762,434,1090,270,1582,926,598,1254,65,1377, + 1028,208,1520,864,536,1192,126,1438,782,454,1110,290,1602,946,618,1274,1271,1315,659,331,1643,987,167,1479,823,495,1151,85,1397,741,413,1069,249,1561,905,577,1233,44,1356,700,372, + 1553,897,569,1225,159,1471,815,487,1143,323,1635,979,651,1307,36,1348,692,364,1676,1020,200,1512,856,528,1184,118,1430,774,446,1102,282,1594,938,610,1266,77,1389,733,405,1061,241, + 549,1205,139,1451,795,467,1123,303,1615,959,631,1287,16,1328,672,344,1656,1000,180,1492,836,508,1164,98,1410,754,426,1082,262,1574,918,590,1246,57,1369,713,385,1041,221,1533,877, + 149,1461,805,477,1133,313,1625,969,641,1297,26,1338,682,354,1666,1010,190,1502,846,518,1174,108,1420,764,436,1092,272,1584,928,600,1256,67,1379,723,395,1051,231,1543,887,559,1215, + 785,457,1113,293,1605,949,621,1277,6,1318,662,334,1646,990,170,1482,826,498,1154,88,1400,744,416,1072,252,1564,908,580,1236,47,1359,703,375,1031,211,1523,867,539,1195,129,1441, + 1138,318,1630,974,646,1302,31,1343,687,359,1671,1015,195,1507,851,523,1179,113,1425,769,441,1097,277,1589,933,605,1261,72,1384,728,400,1056,236,1548,892,564,1220,154,1466,810,482, + 1610,954,626,1282,11,1323,667,339,1651,995,175,1487,831,503,1159,93,1405,749,421,1077,257,1569,913,585,1241,52,1364,708,380,1036,216,1528,872,544,1200,134,1446,790,462,1118,298, + 636,1292,21,1333,677,349,1661,1005,185,1497,841,513,1169,103,1415,759,431,1087,267,1579,923,595,1251,62,1374,718,390,1046,226,1538,882,554,1210,144,1456,800,472,1128,308,1620,964, + 0,1312,656,328,1640,984,164,1476,820,492,1148,82,1394,738,410,1066,246,1558,902,574,1230,41,1353,697,369,1025,205,1517,861,533,1189,123,1435,779,451,1107,287,1599,943,615,3 +}; + +int tableh19[] = { /* 43 x 43 data */ + 2,359,1735,1047,187,1563,875,531,1219,101,1477,789,445,1821,1133,273,1649,961,617,1305,58,1434,746,402,1778,1090,230,1606,918,574,1262,144,1520,832,488,1176,316,1692,1004,660,1348,15,1, + 1746,1058,198,1574,886,542,1230,112,1488,800,456,1832,1144,284,1660,972,628,1316,69,1445,757,413,1789,1101,241,1617,929,585,1273,155,1531,843,499,1187,327,1703,1015,671,1359,26,1402,714,370, + 176,1552,864,520,1208,90,1466,778,434,1810,1122,262,1638,950,606,1294,47,1423,735,391,1767,1079,219,1595,907,563,1251,133,1509,821,477,1165,305,1681,993,649,1337,4,1380,692,348,1724,1036, + 899,555,1243,125,1501,813,469,1845,1157,297,1673,985,641,1329,82,1458,770,426,1802,1114,254,1630,942,598,1286,168,1544,856,512,1200,340,1716,1028,684,1372,39,1415,727,383,1759,1071,211,1587, + 1222,104,1480,792,448,1824,1136,276,1652,964,620,1308,61,1437,749,405,1781,1093,233,1609,921,577,1265,147,1523,835,491,1179,319,1695,1007,663,1351,18,1394,706,362,1738,1050,190,1566,878,534, + 1491,803,459,1835,1147,287,1663,975,631,1319,72,1448,760,416,1792,1104,244,1620,932,588,1276,158,1534,846,502,1190,330,1706,1018,674,1362,29,1405,717,373,1749,1061,201,1577,889,545,1233,115, + 437,1813,1125,265,1641,953,609,1297,50,1426,738,394,1770,1082,222,1598,910,566,1254,136,1512,824,480,1168,308,1684,996,652,1340,7,1383,695,351,1727,1039,179,1555,867,523,1211,93,1469,781, + 1152,292,1668,980,636,1324,77,1453,765,421,1797,1109,249,1625,937,593,1281,163,1539,851,507,1195,335,1711,1023,679,1367,34,1410,722,378,1754,1066,206,1582,894,550,1238,120,1496,808,464,1840, + 1646,958,614,1302,55,1431,743,399,1775,1087,227,1603,915,571,1259,141,1517,829,485,1173,313,1689,1001,657,1345,12,1388,700,356,1732,1044,184,1560,872,528,1216,98,1474,786,442,1818,1130,270, + 625,1313,66,1442,754,410,1786,1098,238,1614,926,582,1270,152,1528,840,496,1184,324,1700,1012,668,1356,23,1399,711,367,1743,1055,195,1571,883,539,1227,109,1485,797,453,1829,1141,281,1657,969, + 44,1420,732,388,1764,1076,216,1592,904,560,1248,130,1506,818,474,1162,302,1678,990,646,1334,1391,1377,689,345,1721,1033,173,1549,861,517,1205,87,1463,775,431,1807,1119,259,1635,947,603,1291, + 773,429,1805,1117,257,1633,945,601,1289,171,1547,859,515,1203,343,1719,1031,687,1375,42,1418,730,386,1762,1074,214,1590,902,558,1246,128,1504,816,472,1848,1160,300,1676,988,644,1332,85,1461, + 1784,1096,236,1612,924,580,1268,150,1526,838,494,1182,322,1698,1010,666,1354,21,1397,709,365,1741,1053,193,1569,881,537,1225,107,1483,795,451,1827,1139,279,1655,967,623,1311,64,1440,752,408, + 247,1623,935,591,1279,161,1537,849,505,1193,333,1709,1021,677,1365,32,1408,720,376,1752,1064,204,1580,892,548,1236,118,1494,806,462,1838,1150,290,1666,978,634,1322,75,1451,763,419,1795,1107, + 913,569,1257,139,1515,827,483,1171,311,1687,999,655,1343,10,1386,698,354,1730,1042,182,1558,870,526,1214,96,1472,784,440,1816,1128,268,1644,956,612,1300,53,1429,741,397,1773,1085,225,1601, + 1284,166,1542,854,510,1198,338,1714,1026,682,1370,37,1413,725,381,1757,1069,209,1585,897,553,1241,123,1499,811,467,1843,1155,295,1671,983,639,1327,80,1456,768,424,1800,1112,252,1628,940,596, + 1521,833,489,1177,317,1693,1005,661,1349,16,1392,704,360,1736,1048,188,1564,876,532,1220,102,1478,790,446,1822,1134,274,1650,962,618,1306,59,1435,747,403,1779,1091,231,1607,919,575,1263,145, + 500,1188,328,1704,1016,672,1360,27,1403,715,371,1747,1059,199,1575,887,543,1231,113,1489,801,457,1833,1145,285,1661,973,629,1317,70,1446,758,414,1790,1102,242,1618,930,586,1274,156,1532,844, + 306,1682,994,650,1338,5,1381,693,349,1725,1037,177,1553,865,521,1209,91,1467,779,435,1811,1123,263,1639,951,607,1295,48,1424,736,392,1768,1080,220,1596,908,564,1252,134,1510,822,478,1166, + 1029,685,1373,40,1416,728,384,1760,1072,212,1588,900,556,1244,126,1502,814,470,1846,1158,298,1674,986,642,1330,83,1459,771,427,1803,1115,255,1631,943,599,1287,169,1545,857,513,1201,341,1717, + 1352,19,1395,707,363,1739,1051,191,1567,879,535,1223,105,1481,793,449,1825,1137,277,1653,965,621,1309,62,1438,750,406,1782,1094,234,1610,922,578,1266,148,1524,836,492,1180,320,1696,1008,664, + 1406,718,374,1750,1062,202,1578,890,546,1234,116,1492,804,460,1836,1148,288,1664,976,632,1320,73,1449,761,417,1793,1105,245,1621,933,589,1277,159,1535,847,503,1191,331,1707,1019,675,1363,30, + 352,1728,1040,180,1556,868,524,1212,94,1470,782,438,1814,1126,266,1642,954,610,1298,51,1427,739,395,1771,1083,223,1599,911,567,1255,137,1513,825,481,1169,309,1685,997,653,1341,8,1384,696, + 1067,207,1583,895,551,1239,121,1497,809,465,1841,1153,293,1669,981,637,1325,78,1454,766,422,1798,1110,250,1626,938,594,1282,164,1540,852,508,1196,336,1712,1024,680,1368,35,1411,723,379,1755, + 1561,873,529,1217,99,1475,787,443,1819,1131,271,1647,959,615,1303,56,1432,744,400,1776,1088,228,1604,916,572,1260,142,1518,830,486,1174,314,1690,1002,658,1346,13,1389,701,357,1733,1045,185, + 540,1228,110,1486,798,454,1830,1142,282,1658,970,626,1314,67,1443,755,411,1787,1099,239,1615,927,583,1271,153,1529,841,497,1185,325,1701,1013,669,1357,24,1400,712,368,1744,1056,196,1572,884, + 88,1464,776,432,1808,1120,260,1636,948,604,1292,45,1421,733,389,1765,1077,217,1593,905,561,1249,131,1507,819,475,1163,303,1679,991,647,1335,703,1378,690,346,1722,1034,174,1550,862,518,1206, + 815,471,1847,1159,299,1675,987,643,1331,84,1460,772,428,1804,1116,256,1632,944,600,1288,170,1546,858,514,1202,342,1718,1030,686,1374,41,1417,729,385,1761,1073,213,1589,901,557,1245,127,1503, + 1826,1138,278,1654,966,622,1310,63,1439,751,407,1783,1095,235,1611,923,579,1267,149,1525,837,493,1181,321,1697,1009,665,1353,20,1396,708,364,1740,1052,192,1568,880,536,1224,106,1482,794,450, + 289,1665,977,633,1321,74,1450,762,418,1794,1106,246,1622,934,590,1278,160,1536,848,504,1192,332,1708,1020,676,1364,31,1407,719,375,1751,1063,203,1579,891,547,1235,117,1493,805,461,1837,1149, + 955,611,1299,52,1428,740,396,1772,1084,224,1600,912,568,1256,138,1514,826,482,1170,310,1686,998,654,1342,9,1385,697,353,1729,1041,181,1557,869,525,1213,95,1471,783,439,1815,1127,267,1643, + 1326,79,1455,767,423,1799,1111,251,1627,939,595,1283,165,1541,853,509,1197,337,1713,1025,681,1369,36,1412,724,380,1756,1068,208,1584,896,552,1240,122,1498,810,466,1842,1154,294,1670,982,638, + 1433,745,401,1777,1089,229,1605,917,573,1261,143,1519,831,487,1175,315,1691,1003,659,1347,14,1390,702,358,1734,1046,186,1562,874,530,1218,100,1476,788,444,1820,1132,272,1648,960,616,1304,57, + 412,1788,1100,240,1616,928,584,1272,154,1530,842,498,1186,326,1702,1014,670,1358,25,1401,713,369,1745,1057,197,1573,885,541,1229,111,1487,799,455,1831,1143,283,1659,971,627,1315,68,1444,756, + 1078,218,1594,906,562,1250,132,1508,820,476,1164,304,1680,992,648,1336,1333,1379,691,347,1723,1035,175,1551,863,519,1207,89,1465,777,433,1809,1121,261,1637,949,605,1293,46,1422,734,390,1766, + 1629,941,597,1285,167,1543,855,511,1199,339,1715,1027,683,1371,38,1414,726,382,1758,1070,210,1586,898,554,1242,124,1500,812,468,1844,1156,296,1672,984,640,1328,81,1457,769,425,1801,1113,253, + 576,1264,146,1522,834,490,1178,318,1694,1006,662,1350,17,1393,705,361,1737,1049,189,1565,877,533,1221,103,1479,791,447,1823,1135,275,1651,963,619,1307,60,1436,748,404,1780,1092,232,1608,920, + 157,1533,845,501,1189,329,1705,1017,673,1361,28,1404,716,372,1748,1060,200,1576,888,544,1232,114,1490,802,458,1834,1146,286,1662,974,630,1318,71,1447,759,415,1791,1103,243,1619,931,587,1275, + 823,479,1167,307,1683,995,651,1339,6,1382,694,350,1726,1038,178,1554,866,522,1210,92,1468,780,436,1812,1124,264,1640,952,608,1296,49,1425,737,393,1769,1081,221,1597,909,565,1253,135,1511, + 1194,334,1710,1022,678,1366,33,1409,721,377,1753,1065,205,1581,893,549,1237,119,1495,807,463,1839,1151,291,1667,979,635,1323,76,1452,764,420,1796,1108,248,1624,936,592,1280,162,1538,850,506, + 1688,1000,656,1344,11,1387,699,355,1731,1043,183,1559,871,527,1215,97,1473,785,441,1817,1129,269,1645,957,613,1301,54,1430,742,398,1774,1086,226,1602,914,570,1258,140,1516,828,484,1172,312, + 667,1355,22,1398,710,366,1742,1054,194,1570,882,538,1226,108,1484,796,452,1828,1140,280,1656,968,624,1312,65,1441,753,409,1785,1097,237,1613,925,581,1269,151,1527,839,495,1183,323,1699,1011, + 0,1376,688,344,1720,1032,172,1548,860,516,1204,86,1462,774,430,1806,1118,258,1634,946,602,1290,43,1419,731,387,1763,1075,215,1591,903,559,1247,129,1505,817,473,1161,301,1677,989,645,3 +}; + +int tableh20[] = { /* 45 x 45 data */ + 2,370,1810,1090,190,1630,910,550,1990,1270,100,1540,820,460,1900,1180,280,1720,1000,640,1360,55,1495,775,415,1855,1135,235,1675,955,595,1315,145,1585,865,505,1945,1225,325,1765,1045,685,1405,10,1, + 1838,1118,218,1658,938,578,2018,1298,128,1568,848,488,1928,1208,308,1748,1028,668,1388,83,1523,803,443,1883,1163,263,1703,983,623,1343,173,1613,893,533,1973,1253,353,1793,1073,713,1433,38,1478,758,398, + 196,1636,916,556,1996,1276,106,1546,826,466,1906,1186,286,1726,1006,646,1366,61,1501,781,421,1861,1141,241,1681,961,601,1321,151,1591,871,511,1951,1231,331,1771,1051,691,1411,16,1456,736,376,1816,1096, + 927,567,2007,1287,117,1557,837,477,1917,1197,297,1737,1017,657,1377,72,1512,792,432,1872,1152,252,1692,972,612,1332,162,1602,882,522,1962,1242,342,1782,1062,702,1422,27,1467,747,387,1827,1107,207,1647, + 1984,1264,94,1534,814,454,1894,1174,274,1714,994,634,1354,49,1489,769,409,1849,1129,229,1669,949,589,1309,139,1579,859,499,1939,1219,319,1759,1039,679,1399,4,1444,724,364,1804,1084,184,1624,904,544, + 131,1571,851,491,1931,1211,311,1751,1031,671,1391,86,1526,806,446,1886,1166,266,1706,986,626,1346,176,1616,896,536,1976,1256,356,1796,1076,716,1436,41,1481,761,401,1841,1121,221,1661,941,581,2021,1301, + 829,469,1909,1189,289,1729,1009,649,1369,64,1504,784,424,1864,1144,244,1684,964,604,1324,154,1594,874,514,1954,1234,334,1774,1054,694,1414,19,1459,739,379,1819,1099,199,1639,919,559,1999,1279,109,1549, + 1920,1200,300,1740,1020,660,1380,75,1515,795,435,1875,1155,255,1695,975,615,1335,165,1605,885,525,1965,1245,345,1785,1065,705,1425,30,1470,750,390,1830,1110,210,1650,930,570,2010,1290,120,1560,840,480, + 277,1717,997,637,1357,52,1492,772,412,1852,1132,232,1672,952,592,1312,142,1582,862,502,1942,1222,322,1762,1042,682,1402,7,1447,727,367,1807,1087,187,1627,907,547,1987,1267,97,1537,817,457,1897,1177, + 1025,665,1385,80,1520,800,440,1880,1160,260,1700,980,620,1340,170,1610,890,530,1970,1250,350,1790,1070,710,1430,35,1475,755,395,1835,1115,215,1655,935,575,2015,1295,125,1565,845,485,1925,1205,305,1745, + 1363,58,1498,778,418,1858,1138,238,1678,958,598,1318,148,1588,868,508,1948,1228,328,1768,1048,688,1408,13,1453,733,373,1813,1093,193,1633,913,553,1993,1273,103,1543,823,463,1903,1183,283,1723,1003,643, + 1509,789,429,1869,1149,249,1689,969,609,1329,159,1599,879,519,1959,1239,339,1779,1059,699,1419,24,1464,744,384,1824,1104,204,1644,924,564,2004,1284,114,1554,834,474,1914,1194,294,1734,1014,654,1374,69, + 406,1846,1126,226,1666,946,586,1306,136,1576,856,496,1936,1216,316,1756,1036,676,1396,1450,1441,721,361,1801,1081,181,1621,901,541,1981,1261,91,1531,811,451,1891,1171,271,1711,991,631,1351,46,1486,766, + 1169,269,1709,989,629,1349,179,1619,899,539,1979,1259,359,1799,1079,719,1439,44,1484,764,404,1844,1124,224,1664,944,584,2024,1304,134,1574,854,494,1934,1214,314,1754,1034,674,1394,89,1529,809,449,1889, + 1687,967,607,1327,157,1597,877,517,1957,1237,337,1777,1057,697,1417,22,1462,742,382,1822,1102,202,1642,922,562,2002,1282,112,1552,832,472,1912,1192,292,1732,1012,652,1372,67,1507,787,427,1867,1147,247, + 618,1338,168,1608,888,528,1968,1248,348,1788,1068,708,1428,33,1473,753,393,1833,1113,213,1653,933,573,2013,1293,123,1563,843,483,1923,1203,303,1743,1023,663,1383,78,1518,798,438,1878,1158,258,1698,978, + 146,1586,866,506,1946,1226,326,1766,1046,686,1406,11,1451,731,371,1811,1091,191,1631,911,551,1991,1271,101,1541,821,461,1901,1181,281,1721,1001,641,1361,56,1496,776,416,1856,1136,236,1676,956,596,1316, + 894,534,1974,1254,354,1794,1074,714,1434,39,1479,759,399,1839,1119,219,1659,939,579,2019,1299,129,1569,849,489,1929,1209,309,1749,1029,669,1389,84,1524,804,444,1884,1164,264,1704,984,624,1344,174,1614, + 1952,1232,332,1772,1052,692,1412,17,1457,737,377,1817,1097,197,1637,917,557,1997,1277,107,1547,827,467,1907,1187,287,1727,1007,647,1367,62,1502,782,422,1862,1142,242,1682,962,602,1322,152,1592,872,512, + 343,1783,1063,703,1423,28,1468,748,388,1828,1108,208,1648,928,568,2008,1288,118,1558,838,478,1918,1198,298,1738,1018,658,1378,73,1513,793,433,1873,1153,253,1693,973,613,1333,163,1603,883,523,1963,1243, + 1040,680,1400,5,1445,725,365,1805,1085,185,1625,905,545,1985,1265,95,1535,815,455,1895,1175,275,1715,995,635,1355,50,1490,770,410,1850,1130,230,1670,950,590,1310,140,1580,860,500,1940,1220,320,1760, + 1437,42,1482,762,402,1842,1122,222,1662,942,582,2022,1302,132,1572,852,492,1932,1212,312,1752,1032,672,1392,87,1527,807,447,1887,1167,267,1707,987,627,1347,177,1617,897,537,1977,1257,357,1797,1077,717, + 1460,740,380,1820,1100,200,1640,920,560,2000,1280,110,1550,830,470,1910,1190,290,1730,1010,650,1370,65,1505,785,425,1865,1145,245,1685,965,605,1325,155,1595,875,515,1955,1235,335,1775,1055,695,1415,20, + 391,1831,1111,211,1651,931,571,2011,1291,121,1561,841,481,1921,1201,301,1741,1021,661,1381,76,1516,796,436,1876,1156,256,1696,976,616,1336,166,1606,886,526,1966,1246,346,1786,1066,706,1426,31,1471,751, + 1088,188,1628,908,548,1988,1268,98,1538,818,458,1898,1178,278,1718,998,638,1358,53,1493,773,413,1853,1133,233,1673,953,593,1313,143,1583,863,503,1943,1223,323,1763,1043,683,1403,8,1448,728,368,1808, + 1656,936,576,2016,1296,126,1566,846,486,1926,1206,306,1746,1026,666,1386,81,1521,801,441,1881,1161,261,1701,981,621,1341,171,1611,891,531,1971,1251,351,1791,1071,711,1431,36,1476,756,396,1836,1116,216, + 554,1994,1274,104,1544,824,464,1904,1184,284,1724,1004,644,1364,59,1499,779,419,1859,1139,239,1679,959,599,1319,149,1589,869,509,1949,1229,329,1769,1049,689,1409,14,1454,734,374,1814,1094,194,1634,914, + 1285,115,1555,835,475,1915,1195,295,1735,1015,655,1375,70,1510,790,430,1870,1150,250,1690,970,610,1330,160,1600,880,520,1960,1240,340,1780,1060,700,1420,25,1465,745,385,1825,1105,205,1645,925,565,2005, + 1532,812,452,1892,1172,272,1712,992,632,1352,47,1487,767,407,1847,1127,227,1667,947,587,1307,137,1577,857,497,1937,1217,317,1757,1037,677,1397,730,1442,722,362,1802,1082,182,1622,902,542,1982,1262,92, + 493,1933,1213,313,1753,1033,673,1393,88,1528,808,448,1888,1168,268,1708,988,628,1348,178,1618,898,538,1978,1258,358,1798,1078,718,1438,43,1483,763,403,1843,1123,223,1663,943,583,2023,1303,133,1573,853, + 1191,291,1731,1011,651,1371,66,1506,786,426,1866,1146,246,1686,966,606,1326,156,1596,876,516,1956,1236,336,1776,1056,696,1416,21,1461,741,381,1821,1101,201,1641,921,561,2001,1281,111,1551,831,471,1911, + 1742,1022,662,1382,77,1517,797,437,1877,1157,257,1697,977,617,1337,167,1607,887,527,1967,1247,347,1787,1067,707,1427,32,1472,752,392,1832,1112,212,1652,932,572,2012,1292,122,1562,842,482,1922,1202,302, + 639,1359,54,1494,774,414,1854,1134,234,1674,954,594,1314,144,1584,864,504,1944,1224,324,1764,1044,684,1404,9,1449,729,369,1809,1089,189,1629,909,549,1989,1269,99,1539,819,459,1899,1179,279,1719,999, + 82,1522,802,442,1882,1162,262,1702,982,622,1342,172,1612,892,532,1972,1252,352,1792,1072,712,1432,37,1477,757,397,1837,1117,217,1657,937,577,2017,1297,127,1567,847,487,1927,1207,307,1747,1027,667,1387, + 780,420,1860,1140,240,1680,960,600,1320,150,1590,870,510,1950,1230,330,1770,1050,690,1410,15,1455,735,375,1815,1095,195,1635,915,555,1995,1275,105,1545,825,465,1905,1185,285,1725,1005,645,1365,60,1500, + 1871,1151,251,1691,971,611,1331,161,1601,881,521,1961,1241,341,1781,1061,701,1421,26,1466,746,386,1826,1106,206,1646,926,566,2006,1286,116,1556,836,476,1916,1196,296,1736,1016,656,1376,71,1511,791,431, + 228,1668,948,588,1308,138,1578,858,498,1938,1218,318,1758,1038,678,1398,1395,1443,723,363,1803,1083,183,1623,903,543,1983,1263,93,1533,813,453,1893,1173,273,1713,993,633,1353,48,1488,768,408,1848,1128, + 985,625,1345,175,1615,895,535,1975,1255,355,1795,1075,715,1435,40,1480,760,400,1840,1120,220,1660,940,580,2020,1300,130,1570,850,490,1930,1210,310,1750,1030,670,1390,85,1525,805,445,1885,1165,265,1705, + 1323,153,1593,873,513,1953,1233,333,1773,1053,693,1413,18,1458,738,378,1818,1098,198,1638,918,558,1998,1278,108,1548,828,468,1908,1188,288,1728,1008,648,1368,63,1503,783,423,1863,1143,243,1683,963,603, + 1604,884,524,1964,1244,344,1784,1064,704,1424,29,1469,749,389,1829,1109,209,1649,929,569,2009,1289,119,1559,839,479,1919,1199,299,1739,1019,659,1379,74,1514,794,434,1874,1154,254,1694,974,614,1334,164, + 501,1941,1221,321,1761,1041,681,1401,6,1446,726,366,1806,1086,186,1626,906,546,1986,1266,96,1536,816,456,1896,1176,276,1716,996,636,1356,51,1491,771,411,1851,1131,231,1671,951,591,1311,141,1581,861, + 1249,349,1789,1069,709,1429,34,1474,754,394,1834,1114,214,1654,934,574,2014,1294,124,1564,844,484,1924,1204,304,1744,1024,664,1384,79,1519,799,439,1879,1159,259,1699,979,619,1339,169,1609,889,529,1969, + 1767,1047,687,1407,12,1452,732,372,1812,1092,192,1632,912,552,1992,1272,102,1542,822,462,1902,1182,282,1722,1002,642,1362,57,1497,777,417,1857,1137,237,1677,957,597,1317,147,1587,867,507,1947,1227,327, + 698,1418,23,1463,743,383,1823,1103,203,1643,923,563,2003,1283,113,1553,833,473,1913,1193,293,1733,1013,653,1373,68,1508,788,428,1868,1148,248,1688,968,608,1328,158,1598,878,518,1958,1238,338,1778,1058, + 0,1440,720,360,1800,1080,180,1620,900,540,1980,1260,90,1530,810,450,1890,1170,270,1710,990,630,1350,45,1485,765,405,1845,1125,225,1665,945,585,1305,135,1575,855,495,1935,1215,315,1755,1035,675,3 +}; + +int tableh21[] = { /* 47 x 47 data */ + 2,398,1902,1150,210,1714,962,586,2090,1338,116,1620,868,492,1996,1244,304,1808,1056,680,2184,1432,69,1573,821,445,1949,1197,257,1761,1009,633,2137,1385,163,1667,915,539,2043,1291,351,1855,1103,727,1479,22,1, + 1914,1162,222,1726,974,598,2102,1350,128,1632,880,504,2008,1256,316,1820,1068,692,2196,1444,81,1585,833,457,1961,1209,269,1773,1021,645,2149,1397,175,1679,927,551,2055,1303,363,1867,1115,739,1491,34,1538,786,410, + 198,1702,950,574,2078,1326,104,1608,856,480,1984,1232,292,1796,1044,668,2172,1420,57,1561,809,433,1937,1185,245,1749,997,621,2125,1373,151,1655,903,527,2031,1279,339,1843,1091,715,1467,10,1514,762,386,1890,1138, + 980,604,2108,1356,134,1638,886,510,2014,1262,322,1826,1074,698,2202,1450,87,1591,839,463,1967,1215,275,1779,1027,651,2155,1403,181,1685,933,557,2061,1309,369,1873,1121,745,1497,40,1544,792,416,1920,1168,228,1732, + 2084,1332,110,1614,862,486,1990,1238,298,1802,1050,674,2178,1426,63,1567,815,439,1943,1191,251,1755,1003,627,2131,1379,157,1661,909,533,2037,1285,345,1849,1097,721,1473,16,1520,768,392,1896,1144,204,1708,956,580, + 122,1626,874,498,2002,1250,310,1814,1062,686,2190,1438,75,1579,827,451,1955,1203,263,1767,1015,639,2143,1391,169,1673,921,545,2049,1297,357,1861,1109,733,1485,28,1532,780,404,1908,1156,216,1720,968,592,2096,1344, + 850,474,1978,1226,286,1790,1038,662,2166,1414,51,1555,803,427,1931,1179,239,1743,991,615,2119,1367,145,1649,897,521,2025,1273,333,1837,1085,709,1461,4,1508,756,380,1884,1132,192,1696,944,568,2072,1320,98,1602, + 2017,1265,325,1829,1077,701,2205,1453,90,1594,842,466,1970,1218,278,1782,1030,654,2158,1406,184,1688,936,560,2064,1312,372,1876,1124,748,1500,43,1547,795,419,1923,1171,231,1735,983,607,2111,1359,137,1641,889,513, + 301,1805,1053,677,2181,1429,66,1570,818,442,1946,1194,254,1758,1006,630,2134,1382,160,1664,912,536,2040,1288,348,1852,1100,724,1476,19,1523,771,395,1899,1147,207,1711,959,583,2087,1335,113,1617,865,489,1993,1241, + 1065,689,2193,1441,78,1582,830,454,1958,1206,266,1770,1018,642,2146,1394,172,1676,924,548,2052,1300,360,1864,1112,736,1488,31,1535,783,407,1911,1159,219,1723,971,595,2099,1347,125,1629,877,501,2005,1253,313,1817, + 2169,1417,54,1558,806,430,1934,1182,242,1746,994,618,2122,1370,148,1652,900,524,2028,1276,336,1840,1088,712,1464,7,1511,759,383,1887,1135,195,1699,947,571,2075,1323,101,1605,853,477,1981,1229,289,1793,1041,665, + 84,1588,836,460,1964,1212,272,1776,1024,648,2152,1400,178,1682,930,554,2058,1306,366,1870,1118,742,1494,37,1541,789,413,1917,1165,225,1729,977,601,2105,1353,131,1635,883,507,2011,1259,319,1823,1071,695,2199,1447, + 812,436,1940,1188,248,1752,1000,624,2128,1376,154,1658,906,530,2034,1282,342,1846,1094,718,1470,13,1517,765,389,1893,1141,201,1705,953,577,2081,1329,107,1611,859,483,1987,1235,295,1799,1047,671,2175,1423,60,1564, + 1952,1200,260,1764,1012,636,2140,1388,166,1670,918,542,2046,1294,354,1858,1106,730,1482,25,1529,777,401,1905,1153,213,1717,965,589,2093,1341,119,1623,871,495,1999,1247,307,1811,1059,683,2187,1435,72,1576,824,448, + 236,1740,988,612,2116,1364,142,1646,894,518,2022,1270,330,1834,1082,706,1458,1526,1505,753,377,1881,1129,189,1693,941,565,2069,1317,95,1599,847,471,1975,1223,283,1787,1035,659,2163,1411,48,1552,800,424,1928,1176, + 1033,657,2161,1409,187,1691,939,563,2067,1315,375,1879,1127,751,1503,46,1550,798,422,1926,1174,234,1738,986,610,2114,1362,140,1644,892,516,2020,1268,328,1832,1080,704,2208,1456,93,1597,845,469,1973,1221,281,1785, + 2138,1386,164,1668,916,540,2044,1292,352,1856,1104,728,1480,23,1527,775,399,1903,1151,211,1715,963,587,2091,1339,117,1621,869,493,1997,1245,305,1809,1057,681,2185,1433,70,1574,822,446,1950,1198,258,1762,1010,634, + 176,1680,928,552,2056,1304,364,1868,1116,740,1492,35,1539,787,411,1915,1163,223,1727,975,599,2103,1351,129,1633,881,505,2009,1257,317,1821,1069,693,2197,1445,82,1586,834,458,1962,1210,270,1774,1022,646,2150,1398, + 904,528,2032,1280,340,1844,1092,716,1468,11,1515,763,387,1891,1139,199,1703,951,575,2079,1327,105,1609,857,481,1985,1233,293,1797,1045,669,2173,1421,58,1562,810,434,1938,1186,246,1750,998,622,2126,1374,152,1656, + 2062,1310,370,1874,1122,746,1498,41,1545,793,417,1921,1169,229,1733,981,605,2109,1357,135,1639,887,511,2015,1263,323,1827,1075,699,2203,1451,88,1592,840,464,1968,1216,276,1780,1028,652,2156,1404,182,1686,934,558, + 346,1850,1098,722,1474,17,1521,769,393,1897,1145,205,1709,957,581,2085,1333,111,1615,863,487,1991,1239,299,1803,1051,675,2179,1427,64,1568,816,440,1944,1192,252,1756,1004,628,2132,1380,158,1662,910,534,2038,1286, + 1110,734,1486,29,1533,781,405,1909,1157,217,1721,969,593,2097,1345,123,1627,875,499,2003,1251,311,1815,1063,687,2191,1439,76,1580,828,452,1956,1204,264,1768,1016,640,2144,1392,170,1674,922,546,2050,1298,358,1862, + 1462,5,1509,757,381,1885,1133,193,1697,945,569,2073,1321,99,1603,851,475,1979,1227,287,1791,1039,663,2167,1415,52,1556,804,428,1932,1180,240,1744,992,616,2120,1368,146,1650,898,522,2026,1274,334,1838,1086,710, + 1548,796,420,1924,1172,232,1736,984,608,2112,1360,138,1642,890,514,2018,1266,326,1830,1078,702,2206,1454,91,1595,843,467,1971,1219,279,1783,1031,655,2159,1407,185,1689,937,561,2065,1313,373,1877,1125,749,1501,44, + 396,1900,1148,208,1712,960,584,2088,1336,114,1618,866,490,1994,1242,302,1806,1054,678,2182,1430,67,1571,819,443,1947,1195,255,1759,1007,631,2135,1383,161,1665,913,537,2041,1289,349,1853,1101,725,1477,20,1524,772, + 1160,220,1724,972,596,2100,1348,126,1630,878,502,2006,1254,314,1818,1066,690,2194,1442,79,1583,831,455,1959,1207,267,1771,1019,643,2147,1395,173,1677,925,549,2053,1301,361,1865,1113,737,1489,32,1536,784,408,1912, + 1700,948,572,2076,1324,102,1606,854,478,1982,1230,290,1794,1042,666,2170,1418,55,1559,807,431,1935,1183,243,1747,995,619,2123,1371,149,1653,901,525,2029,1277,337,1841,1089,713,1465,8,1512,760,384,1888,1136,196, + 602,2106,1354,132,1636,884,508,2012,1260,320,1824,1072,696,2200,1448,85,1589,837,461,1965,1213,273,1777,1025,649,2153,1401,179,1683,931,555,2059,1307,367,1871,1119,743,1495,38,1542,790,414,1918,1166,226,1730,978, + 1330,108,1612,860,484,1988,1236,296,1800,1048,672,2176,1424,61,1565,813,437,1941,1189,249,1753,1001,625,2129,1377,155,1659,907,531,2035,1283,343,1847,1095,719,1471,14,1518,766,390,1894,1142,202,1706,954,578,2082, + 1624,872,496,2000,1248,308,1812,1060,684,2188,1436,73,1577,825,449,1953,1201,261,1765,1013,637,2141,1389,167,1671,919,543,2047,1295,355,1859,1107,731,1483,26,1530,778,402,1906,1154,214,1718,966,590,2094,1342,120, + 472,1976,1224,284,1788,1036,660,2164,1412,49,1553,801,425,1929,1177,237,1741,989,613,2117,1365,143,1647,895,519,2023,1271,331,1835,1083,707,1459,774,1506,754,378,1882,1130,190,1694,942,566,2070,1318,96,1600,848, + 1267,327,1831,1079,703,2207,1455,92,1596,844,468,1972,1220,280,1784,1032,656,2160,1408,186,1690,938,562,2066,1314,374,1878,1126,750,1502,45,1549,797,421,1925,1173,233,1737,985,609,2113,1361,139,1643,891,515,2019, + 1807,1055,679,2183,1431,68,1572,820,444,1948,1196,256,1760,1008,632,2136,1384,162,1666,914,538,2042,1290,350,1854,1102,726,1478,21,1525,773,397,1901,1149,209,1713,961,585,2089,1337,115,1619,867,491,1995,1243,303, + 691,2195,1443,80,1584,832,456,1960,1208,268,1772,1020,644,2148,1396,174,1678,926,550,2054,1302,362,1866,1114,738,1490,33,1537,785,409,1913,1161,221,1725,973,597,2101,1349,127,1631,879,503,2007,1255,315,1819,1067, + 1419,56,1560,808,432,1936,1184,244,1748,996,620,2124,1372,150,1654,902,526,2030,1278,338,1842,1090,714,1466,9,1513,761,385,1889,1137,197,1701,949,573,2077,1325,103,1607,855,479,1983,1231,291,1795,1043,667,2171, + 1590,838,462,1966,1214,274,1778,1026,650,2154,1402,180,1684,932,556,2060,1308,368,1872,1120,744,1496,39,1543,791,415,1919,1167,227,1731,979,603,2107,1355,133,1637,885,509,2013,1261,321,1825,1073,697,2201,1449,86, + 438,1942,1190,250,1754,1002,626,2130,1378,156,1660,908,532,2036,1284,344,1848,1096,720,1472,15,1519,767,391,1895,1143,203,1707,955,579,2083,1331,109,1613,861,485,1989,1237,297,1801,1049,673,2177,1425,62,1566,814, + 1202,262,1766,1014,638,2142,1390,168,1672,920,544,2048,1296,356,1860,1108,732,1484,27,1531,779,403,1907,1155,215,1719,967,591,2095,1343,121,1625,873,497,2001,1249,309,1813,1061,685,2189,1437,74,1578,826,450,1954, + 1742,990,614,2118,1366,144,1648,896,520,2024,1272,332,1836,1084,708,1460,1457,1507,755,379,1883,1131,191,1695,943,567,2071,1319,97,1601,849,473,1977,1225,285,1789,1037,661,2165,1413,50,1554,802,426,1930,1178,238, + 653,2157,1405,183,1687,935,559,2063,1311,371,1875,1123,747,1499,42,1546,794,418,1922,1170,230,1734,982,606,2110,1358,136,1640,888,512,2016,1264,324,1828,1076,700,2204,1452,89,1593,841,465,1969,1217,277,1781,1029, + 1381,159,1663,911,535,2039,1287,347,1851,1099,723,1475,18,1522,770,394,1898,1146,206,1710,958,582,2086,1334,112,1616,864,488,1992,1240,300,1804,1052,676,2180,1428,65,1569,817,441,1945,1193,253,1757,1005,629,2133, + 1675,923,547,2051,1299,359,1863,1111,735,1487,30,1534,782,406,1910,1158,218,1722,970,594,2098,1346,124,1628,876,500,2004,1252,312,1816,1064,688,2192,1440,77,1581,829,453,1957,1205,265,1769,1017,641,2145,1393,171, + 523,2027,1275,335,1839,1087,711,1463,6,1510,758,382,1886,1134,194,1698,946,570,2074,1322,100,1604,852,476,1980,1228,288,1792,1040,664,2168,1416,53,1557,805,429,1933,1181,241,1745,993,617,2121,1369,147,1651,899, + 1305,365,1869,1117,741,1493,36,1540,788,412,1916,1164,224,1728,976,600,2104,1352,130,1634,882,506,2010,1258,318,1822,1070,694,2198,1446,83,1587,835,459,1963,1211,271,1775,1023,647,2151,1399,177,1681,929,553,2057, + 1845,1093,717,1469,12,1516,764,388,1892,1140,200,1704,952,576,2080,1328,106,1610,858,482,1986,1234,294,1798,1046,670,2174,1422,59,1563,811,435,1939,1187,247,1751,999,623,2127,1375,153,1657,905,529,2033,1281,341, + 729,1481,24,1528,776,400,1904,1152,212,1716,964,588,2092,1340,118,1622,870,494,1998,1246,306,1810,1058,682,2186,1434,71,1575,823,447,1951,1199,259,1763,1011,635,2139,1387,165,1669,917,541,2045,1293,353,1857,1105, + 0,1504,752,376,1880,1128,188,1692,940,564,2068,1316,94,1598,846,470,1974,1222,282,1786,1034,658,2162,1410,47,1551,799,423,1927,1175,235,1739,987,611,2115,1363,141,1645,893,517,2021,1269,329,1833,1081,705,3 +}; + +int MatrixMaxCapacities[21] = { 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841, 961, 1089, 1225, 1369, 1521, 1681, 1849, 2025, 2209 }; + +int MasterRandomStream[] = { /* From Annex L */ + 0x05,0xff,0xc7,0x31,0x88,0xa8,0x83,0x9c,0x64,0x87,0x9f,0x64,0xb3,0xe0,0x4d,0x9c,0x80,0x29,0x3a,0x90, + 0xb3,0x8b,0x9e,0x90,0x45,0xbf,0xf5,0x68,0x4b,0x08,0xcf,0x44,0xb8,0xd4,0x4c,0x5b,0xa0,0xab,0x72,0x52, + 0x1c,0xe4,0xd2,0x74,0xa4,0xda,0x8a,0x08,0xfa,0xa7,0xc7,0xdd,0x00,0x30,0xa9,0xe6,0x64,0xab,0xd5,0x8b, + 0xed,0x9c,0x79,0xf8,0x08,0xd1,0x8b,0xc6,0x22,0x64,0x0b,0x33,0x43,0xd0,0x80,0xd4,0x44,0x95,0x2e,0x6f, + 0x5e,0x13,0x8d,0x47,0x62,0x06,0xeb,0x80,0x82,0xc9,0x41,0xd5,0x73,0x8a,0x30,0x23,0x24,0xe3,0x7f,0xb2, + 0xa8,0x0b,0xed,0x38,0x42,0x4c,0xd7,0xb0,0xce,0x98,0xbd,0xe1,0xd5,0xe4,0xc3,0x1d,0x15,0x4a,0xcf,0xd1, + 0x1f,0x39,0x26,0x18,0x93,0xfc,0x19,0xb2,0x2d,0xab,0xf2,0x6e,0xa1,0x9f,0xaf,0xd0,0x8a,0x2b,0xa0,0x56, + 0xb0,0x41,0x6d,0x43,0xa4,0x63,0xf3,0xaa,0x7d,0xaf,0x35,0x57,0xc2,0x94,0x4a,0x65,0x0b,0x41,0xde,0xb8, + 0xe2,0x30,0x12,0x27,0x9b,0x66,0x2b,0x34,0x5b,0xb8,0x99,0xe8,0x28,0x71,0xd0,0x95,0x6b,0x07,0x4d,0x3c, + 0x7a,0xb3,0xe5,0x29,0xb3,0xba,0x8c,0xcc,0x2d,0xe0,0xc9,0xc0,0x22,0xec,0x4c,0xde,0xf8,0x58,0x07,0xfc, + 0x19,0xf2,0x64,0xe2,0xc3,0xe2,0xd8,0xb9,0xfd,0x67,0xa0,0xbc,0xf5,0x2e,0xc9,0x49,0x75,0x62,0x82,0x27, + 0x10,0xf4,0x19,0x6f,0x49,0xf7,0xb3,0x84,0x14,0xea,0xeb,0xe1,0x2a,0x31,0xab,0x47,0x7d,0x08,0x29,0xac, + 0xbb,0x72,0xfa,0xfa,0x62,0xb8,0xc8,0xd3,0x86,0x89,0x95,0xfd,0xdf,0xcc,0x9c,0xad,0xf1,0xd4,0x6c,0x64, + 0x23,0x24,0x2a,0x56,0x1f,0x36,0xeb,0xb7,0xd6,0xff,0xda,0x57,0xf4,0x50,0x79,0x08,0x00 +}; \ No newline at end of file diff --git a/backend/font.h b/backend/font.h new file mode 100644 index 00000000..432a3914 --- /dev/null +++ b/backend/font.h @@ -0,0 +1,57 @@ +/* font.h - Font for PNG images */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* This file contains the pixel-by-pixel representation of the "Misc Fixed" font + at 10 point size processed by the Gimp */ + +static int ascii_font[9310] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static int ascii_ext_font[9310] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 +}; diff --git a/backend/gb2312.h b/backend/gb2312.h new file mode 100644 index 00000000..eca1c502 --- /dev/null +++ b/backend/gb2312.h @@ -0,0 +1,7467 @@ +/* gb2312.h - Unicode to GB 2312-1980 lookup table + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +unsigned long int gb2312_lookup[] = { + 0x00A4, 0xA1E8, + 0x00A7, 0xA1EC, + 0x00A8, 0xA1A7, + 0x00B0, 0xA1E3, + 0x00B1, 0xA1C0, + 0x00B7, 0xA1A4, + 0x00D7, 0xA1C1, + 0x00E0, 0xA8A4, + 0x00E1, 0xA8A2, + 0x00E8, 0xA8A8, + 0x00E9, 0xA8A6, + 0x00EA, 0xA8BA, + 0x00EC, 0xA8AC, + 0x00ED, 0xA8AA, + 0x00F2, 0xA8B0, + 0x00F3, 0xA8AE, + 0x00F7, 0xA1C2, + 0x00F9, 0xA8B4, + 0x00FA, 0xA8B2, + 0x00FC, 0xA8B9, + 0x0101, 0xA8A1, + 0x0113, 0xA8A5, + 0x011B, 0xA8A7, + 0x012B, 0xA8A9, + 0x014D, 0xA8AD, + 0x016B, 0xA8B1, + 0x01CE, 0xA8A3, + 0x01D0, 0xA8AB, + 0x01D2, 0xA8AF, + 0x01D4, 0xA8B3, + 0x01D6, 0xA8B5, + 0x01D8, 0xA8B6, + 0x01DA, 0xA8B7, + 0x01DC, 0xA8B8, + 0x02C7, 0xA1A6, + 0x02C9, 0xA1A5, + 0x0391, 0xA6A1, + 0x0392, 0xA6A2, + 0x0393, 0xA6A3, + 0x0394, 0xA6A4, + 0x0395, 0xA6A5, + 0x0396, 0xA6A6, + 0x0397, 0xA6A7, + 0x0398, 0xA6A8, + 0x0399, 0xA6A9, + 0x039A, 0xA6AA, + 0x039B, 0xA6AB, + 0x039C, 0xA6AC, + 0x039D, 0xA6AD, + 0x039E, 0xA6AE, + 0x039F, 0xA6AF, + 0x03A0, 0xA6B0, + 0x03A1, 0xA6B1, + 0x03A3, 0xA6B2, + 0x03A4, 0xA6B3, + 0x03A5, 0xA6B4, + 0x03A6, 0xA6B5, + 0x03A7, 0xA6B6, + 0x03A8, 0xA6B7, + 0x03A9, 0xA6B8, + 0x03B1, 0xA6C1, + 0x03B2, 0xA6C2, + 0x03B3, 0xA6C3, + 0x03B4, 0xA6C4, + 0x03B5, 0xA6C5, + 0x03B6, 0xA6C6, + 0x03B7, 0xA6C7, + 0x03B8, 0xA6C8, + 0x03B9, 0xA6C9, + 0x03BA, 0xA6CA, + 0x03BB, 0xA6CB, + 0x03BC, 0xA6CC, + 0x03BD, 0xA6CD, + 0x03BE, 0xA6CE, + 0x03BF, 0xA6CF, + 0x03C0, 0xA6D0, + 0x03C1, 0xA6D1, + 0x03C3, 0xA6D2, + 0x03C4, 0xA6D3, + 0x03C5, 0xA6D4, + 0x03C6, 0xA6D5, + 0x03C7, 0xA6D6, + 0x03C8, 0xA6D7, + 0x03C9, 0xA6D8, + 0x0401, 0xA7A7, + 0x0410, 0xA7A1, + 0x0411, 0xA7A2, + 0x0412, 0xA7A3, + 0x0413, 0xA7A4, + 0x0414, 0xA7A5, + 0x0415, 0xA7A6, + 0x0416, 0xA7A8, + 0x0417, 0xA7A9, + 0x0418, 0xA7AA, + 0x0419, 0xA7AB, + 0x041A, 0xA7AC, + 0x041B, 0xA7AD, + 0x041C, 0xA7AE, + 0x041D, 0xA7AF, + 0x041E, 0xA7B0, + 0x041F, 0xA7B1, + 0x0420, 0xA7B2, + 0x0421, 0xA7B3, + 0x0422, 0xA7B4, + 0x0423, 0xA7B5, + 0x0424, 0xA7B6, + 0x0425, 0xA7B7, + 0x0426, 0xA7B8, + 0x0427, 0xA7B9, + 0x0428, 0xA7BA, + 0x0429, 0xA7BB, + 0x042A, 0xA7BC, + 0x042B, 0xA7BD, + 0x042C, 0xA7BE, + 0x042D, 0xA7BF, + 0x042E, 0xA7C0, + 0x042F, 0xA7C1, + 0x0430, 0xA7D1, + 0x0431, 0xA7D2, + 0x0432, 0xA7D3, + 0x0433, 0xA7D4, + 0x0434, 0xA7D5, + 0x0435, 0xA7D6, + 0x0436, 0xA7D8, + 0x0437, 0xA7D9, + 0x0438, 0xA7DA, + 0x0439, 0xA7DB, + 0x043A, 0xA7DC, + 0x043B, 0xA7DD, + 0x043C, 0xA7DE, + 0x043D, 0xA7DF, + 0x043E, 0xA7E0, + 0x043F, 0xA7E1, + 0x0440, 0xA7E2, + 0x0441, 0xA7E3, + 0x0442, 0xA7E4, + 0x0443, 0xA7E5, + 0x0444, 0xA7E6, + 0x0445, 0xA7E7, + 0x0446, 0xA7E8, + 0x0447, 0xA7E9, + 0x0448, 0xA7EA, + 0x0449, 0xA7EB, + 0x044A, 0xA7EC, + 0x044B, 0xA7ED, + 0x044C, 0xA7EE, + 0x044D, 0xA7EF, + 0x044E, 0xA7F0, + 0x044F, 0xA7F1, + 0x0451, 0xA7D7, + 0x2014, 0xA1AA, + 0x2016, 0xA1AC, + 0x2018, 0xA1AE, + 0x2019, 0xA1AF, + 0x201C, 0xA1B0, + 0x201D, 0xA1B1, + 0x2026, 0xA1AD, + 0x2030, 0xA1EB, + 0x2032, 0xA1E4, + 0x2033, 0xA1E5, + 0x203B, 0xA1F9, + 0x2103, 0xA1E6, + 0x2116, 0xA1ED, + 0x2160, 0xA2F1, + 0x2161, 0xA2F2, + 0x2162, 0xA2F3, + 0x2163, 0xA2F4, + 0x2164, 0xA2F5, + 0x2165, 0xA2F6, + 0x2166, 0xA2F7, + 0x2167, 0xA2F8, + 0x2168, 0xA2F9, + 0x2169, 0xA2FA, + 0x216A, 0xA2FB, + 0x216B, 0xA2FC, + 0x2190, 0xA1FB, + 0x2191, 0xA1FC, + 0x2192, 0xA1FA, + 0x2193, 0xA1FD, + 0x2208, 0xA1CA, + 0x220F, 0xA1C7, + 0x2211, 0xA1C6, + 0x221A, 0xA1CC, + 0x221D, 0xA1D8, + 0x221E, 0xA1DE, + 0x2220, 0xA1CF, + 0x2225, 0xA1CE, + 0x2227, 0xA1C4, + 0x2228, 0xA1C5, + 0x2229, 0xA1C9, + 0x222A, 0xA1C8, + 0x222B, 0xA1D2, + 0x222E, 0xA1D3, + 0x2234, 0xA1E0, + 0x2235, 0xA1DF, + 0x2236, 0xA1C3, + 0x2237, 0xA1CB, + 0x223D, 0xA1D7, + 0x2248, 0xA1D6, + 0x224C, 0xA1D5, + 0x2260, 0xA1D9, + 0x2261, 0xA1D4, + 0x2264, 0xA1DC, + 0x2265, 0xA1DD, + 0x226E, 0xA1DA, + 0x226F, 0xA1DB, + 0x2299, 0xA1D1, + 0x22A5, 0xA1CD, + 0x2312, 0xA1D0, + 0x2460, 0xA2D9, + 0x2461, 0xA2DA, + 0x2462, 0xA2DB, + 0x2463, 0xA2DC, + 0x2464, 0xA2DD, + 0x2465, 0xA2DE, + 0x2466, 0xA2DF, + 0x2467, 0xA2E0, + 0x2468, 0xA2E1, + 0x2469, 0xA2E2, + 0x2474, 0xA2C5, + 0x2475, 0xA2C6, + 0x2476, 0xA2C7, + 0x2477, 0xA2C8, + 0x2478, 0xA2C9, + 0x2479, 0xA2CA, + 0x247A, 0xA2CB, + 0x247B, 0xA2CC, + 0x247C, 0xA2CD, + 0x247D, 0xA2CE, + 0x247E, 0xA2CF, + 0x247F, 0xA2D0, + 0x2480, 0xA2D1, + 0x2481, 0xA2D2, + 0x2482, 0xA2D3, + 0x2483, 0xA2D4, + 0x2484, 0xA2D5, + 0x2485, 0xA2D6, + 0x2486, 0xA2D7, + 0x2487, 0xA2D8, + 0x2488, 0xA2B1, + 0x2489, 0xA2B2, + 0x248A, 0xA2B3, + 0x248B, 0xA2B4, + 0x248C, 0xA2B5, + 0x248D, 0xA2B6, + 0x248E, 0xA2B7, + 0x248F, 0xA2B8, + 0x2490, 0xA2B9, + 0x2491, 0xA2BA, + 0x2492, 0xA2BB, + 0x2493, 0xA2BC, + 0x2494, 0xA2BD, + 0x2495, 0xA2BE, + 0x2496, 0xA2BF, + 0x2497, 0xA2C0, + 0x2498, 0xA2C1, + 0x2499, 0xA2C2, + 0x249A, 0xA2C3, + 0x249B, 0xA2C4, + 0x2500, 0xA9A4, + 0x2501, 0xA9A5, + 0x2502, 0xA9A6, + 0x2503, 0xA9A7, + 0x2504, 0xA9A8, + 0x2505, 0xA9A9, + 0x2506, 0xA9AA, + 0x2507, 0xA9AB, + 0x2508, 0xA9AC, + 0x2509, 0xA9AD, + 0x250A, 0xA9AE, + 0x250B, 0xA9AF, + 0x250C, 0xA9B0, + 0x250D, 0xA9B1, + 0x250E, 0xA9B2, + 0x250F, 0xA9B3, + 0x2510, 0xA9B4, + 0x2511, 0xA9B5, + 0x2512, 0xA9B6, + 0x2513, 0xA9B7, + 0x2514, 0xA9B8, + 0x2515, 0xA9B9, + 0x2516, 0xA9BA, + 0x2517, 0xA9BB, + 0x2518, 0xA9BC, + 0x2519, 0xA9BD, + 0x251A, 0xA9BE, + 0x251B, 0xA9BF, + 0x251C, 0xA9C0, + 0x251D, 0xA9C1, + 0x251E, 0xA9C2, + 0x251F, 0xA9C3, + 0x2520, 0xA9C4, + 0x2521, 0xA9C5, + 0x2522, 0xA9C6, + 0x2523, 0xA9C7, + 0x2524, 0xA9C8, + 0x2525, 0xA9C9, + 0x2526, 0xA9CA, + 0x2527, 0xA9CB, + 0x2528, 0xA9CC, + 0x2529, 0xA9CD, + 0x252A, 0xA9CE, + 0x252B, 0xA9CF, + 0x252C, 0xA9D0, + 0x252D, 0xA9D1, + 0x252E, 0xA9D2, + 0x252F, 0xA9D3, + 0x2530, 0xA9D4, + 0x2531, 0xA9D5, + 0x2532, 0xA9D6, + 0x2533, 0xA9D7, + 0x2534, 0xA9D8, + 0x2535, 0xA9D9, + 0x2536, 0xA9DA, + 0x2537, 0xA9DB, + 0x2538, 0xA9DC, + 0x2539, 0xA9DD, + 0x253A, 0xA9DE, + 0x253B, 0xA9DF, + 0x253C, 0xA9E0, + 0x253D, 0xA9E1, + 0x253E, 0xA9E2, + 0x253F, 0xA9E3, + 0x2540, 0xA9E4, + 0x2541, 0xA9E5, + 0x2542, 0xA9E6, + 0x2543, 0xA9E7, + 0x2544, 0xA9E8, + 0x2545, 0xA9E9, + 0x2546, 0xA9EA, + 0x2547, 0xA9EB, + 0x2548, 0xA9EC, + 0x2549, 0xA9ED, + 0x254A, 0xA9EE, + 0x254B, 0xA9EF, + 0x25A0, 0xA1F6, + 0x25A1, 0xA1F5, + 0x25B2, 0xA1F8, + 0x25B3, 0xA1F7, + 0x25C6, 0xA1F4, + 0x25C7, 0xA1F3, + 0x25CB, 0xA1F0, + 0x25CE, 0xA1F2, + 0x25CF, 0xA1F1, + 0x2605, 0xA1EF, + 0x2606, 0xA1EE, + 0x2640, 0xA1E2, + 0x2642, 0xA1E1, + 0x3000, 0xA1A1, + 0x3001, 0xA1A2, + 0x3002, 0xA1A3, + 0x3003, 0xA1A8, + 0x3005, 0xA1A9, + 0x3008, 0xA1B4, + 0x3009, 0xA1B5, + 0x300A, 0xA1B6, + 0x300B, 0xA1B7, + 0x300C, 0xA1B8, + 0x300D, 0xA1B9, + 0x300E, 0xA1BA, + 0x300F, 0xA1BB, + 0x3010, 0xA1BE, + 0x3011, 0xA1BF, + 0x3013, 0xA1FE, + 0x3014, 0xA1B2, + 0x3015, 0xA1B3, + 0x3016, 0xA1BC, + 0x3017, 0xA1BD, + 0x3041, 0xA4A1, + 0x3042, 0xA4A2, + 0x3043, 0xA4A3, + 0x3044, 0xA4A4, + 0x3045, 0xA4A5, + 0x3046, 0xA4A6, + 0x3047, 0xA4A7, + 0x3048, 0xA4A8, + 0x3049, 0xA4A9, + 0x304A, 0xA4AA, + 0x304B, 0xA4AB, + 0x304C, 0xA4AC, + 0x304D, 0xA4AD, + 0x304E, 0xA4AE, + 0x304F, 0xA4AF, + 0x3050, 0xA4B0, + 0x3051, 0xA4B1, + 0x3052, 0xA4B2, + 0x3053, 0xA4B3, + 0x3054, 0xA4B4, + 0x3055, 0xA4B5, + 0x3056, 0xA4B6, + 0x3057, 0xA4B7, + 0x3058, 0xA4B8, + 0x3059, 0xA4B9, + 0x305A, 0xA4BA, + 0x305B, 0xA4BB, + 0x305C, 0xA4BC, + 0x305D, 0xA4BD, + 0x305E, 0xA4BE, + 0x305F, 0xA4BF, + 0x3060, 0xA4C0, + 0x3061, 0xA4C1, + 0x3062, 0xA4C2, + 0x3063, 0xA4C3, + 0x3064, 0xA4C4, + 0x3065, 0xA4C5, + 0x3066, 0xA4C6, + 0x3067, 0xA4C7, + 0x3068, 0xA4C8, + 0x3069, 0xA4C9, + 0x306A, 0xA4CA, + 0x306B, 0xA4CB, + 0x306C, 0xA4CC, + 0x306D, 0xA4CD, + 0x306E, 0xA4CE, + 0x306F, 0xA4CF, + 0x3070, 0xA4D0, + 0x3071, 0xA4D1, + 0x3072, 0xA4D2, + 0x3073, 0xA4D3, + 0x3074, 0xA4D4, + 0x3075, 0xA4D5, + 0x3076, 0xA4D6, + 0x3077, 0xA4D7, + 0x3078, 0xA4D8, + 0x3079, 0xA4D9, + 0x307A, 0xA4DA, + 0x307B, 0xA4DB, + 0x307C, 0xA4DC, + 0x307D, 0xA4DD, + 0x307E, 0xA4DE, + 0x307F, 0xA4DF, + 0x3080, 0xA4E0, + 0x3081, 0xA4E1, + 0x3082, 0xA4E2, + 0x3083, 0xA4E3, + 0x3084, 0xA4E4, + 0x3085, 0xA4E5, + 0x3086, 0xA4E6, + 0x3087, 0xA4E7, + 0x3088, 0xA4E8, + 0x3089, 0xA4E9, + 0x308A, 0xA4EA, + 0x308B, 0xA4EB, + 0x308C, 0xA4EC, + 0x308D, 0xA4ED, + 0x308E, 0xA4EE, + 0x308F, 0xA4EF, + 0x3090, 0xA4F0, + 0x3091, 0xA4F1, + 0x3092, 0xA4F2, + 0x3093, 0xA4F3, + 0x30A1, 0xA5A1, + 0x30A2, 0xA5A2, + 0x30A3, 0xA5A3, + 0x30A4, 0xA5A4, + 0x30A5, 0xA5A5, + 0x30A6, 0xA5A6, + 0x30A7, 0xA5A7, + 0x30A8, 0xA5A8, + 0x30A9, 0xA5A9, + 0x30AA, 0xA5AA, + 0x30AB, 0xA5AB, + 0x30AC, 0xA5AC, + 0x30AD, 0xA5AD, + 0x30AE, 0xA5AE, + 0x30AF, 0xA5AF, + 0x30B0, 0xA5B0, + 0x30B1, 0xA5B1, + 0x30B2, 0xA5B2, + 0x30B3, 0xA5B3, + 0x30B4, 0xA5B4, + 0x30B5, 0xA5B5, + 0x30B6, 0xA5B6, + 0x30B7, 0xA5B7, + 0x30B8, 0xA5B8, + 0x30B9, 0xA5B9, + 0x30BA, 0xA5BA, + 0x30BB, 0xA5BB, + 0x30BC, 0xA5BC, + 0x30BD, 0xA5BD, + 0x30BE, 0xA5BE, + 0x30BF, 0xA5BF, + 0x30C0, 0xA5C0, + 0x30C1, 0xA5C1, + 0x30C2, 0xA5C2, + 0x30C3, 0xA5C3, + 0x30C4, 0xA5C4, + 0x30C5, 0xA5C5, + 0x30C6, 0xA5C6, + 0x30C7, 0xA5C7, + 0x30C8, 0xA5C8, + 0x30C9, 0xA5C9, + 0x30CA, 0xA5CA, + 0x30CB, 0xA5CB, + 0x30CC, 0xA5CC, + 0x30CD, 0xA5CD, + 0x30CE, 0xA5CE, + 0x30CF, 0xA5CF, + 0x30D0, 0xA5D0, + 0x30D1, 0xA5D1, + 0x30D2, 0xA5D2, + 0x30D3, 0xA5D3, + 0x30D4, 0xA5D4, + 0x30D5, 0xA5D5, + 0x30D6, 0xA5D6, + 0x30D7, 0xA5D7, + 0x30D8, 0xA5D8, + 0x30D9, 0xA5D9, + 0x30DA, 0xA5DA, + 0x30DB, 0xA5DB, + 0x30DC, 0xA5DC, + 0x30DD, 0xA5DD, + 0x30DE, 0xA5DE, + 0x30DF, 0xA5DF, + 0x30E0, 0xA5E0, + 0x30E1, 0xA5E1, + 0x30E2, 0xA5E2, + 0x30E3, 0xA5E3, + 0x30E4, 0xA5E4, + 0x30E5, 0xA5E5, + 0x30E6, 0xA5E6, + 0x30E7, 0xA5E7, + 0x30E8, 0xA5E8, + 0x30E9, 0xA5E9, + 0x30EA, 0xA5EA, + 0x30EB, 0xA5EB, + 0x30EC, 0xA5EC, + 0x30ED, 0xA5ED, + 0x30EE, 0xA5EE, + 0x30EF, 0xA5EF, + 0x30F0, 0xA5F0, + 0x30F1, 0xA5F1, + 0x30F2, 0xA5F2, + 0x30F3, 0xA5F3, + 0x30F4, 0xA5F4, + 0x30F5, 0xA5F5, + 0x30F6, 0xA5F6, + 0x3105, 0xA8C5, + 0x3106, 0xA8C6, + 0x3107, 0xA8C7, + 0x3108, 0xA8C8, + 0x3109, 0xA8C9, + 0x310A, 0xA8CA, + 0x310B, 0xA8CB, + 0x310C, 0xA8CC, + 0x310D, 0xA8CD, + 0x310E, 0xA8CE, + 0x310F, 0xA8CF, + 0x3110, 0xA8D0, + 0x3111, 0xA8D1, + 0x3112, 0xA8D2, + 0x3113, 0xA8D3, + 0x3114, 0xA8D4, + 0x3115, 0xA8D5, + 0x3116, 0xA8D6, + 0x3117, 0xA8D7, + 0x3118, 0xA8D8, + 0x3119, 0xA8D9, + 0x311A, 0xA8DA, + 0x311B, 0xA8DB, + 0x311C, 0xA8DC, + 0x311D, 0xA8DD, + 0x311E, 0xA8DE, + 0x311F, 0xA8DF, + 0x3120, 0xA8E0, + 0x3121, 0xA8E1, + 0x3122, 0xA8E2, + 0x3123, 0xA8E3, + 0x3124, 0xA8E4, + 0x3125, 0xA8E5, + 0x3126, 0xA8E6, + 0x3127, 0xA8E7, + 0x3128, 0xA8E8, + 0x3129, 0xA8E9, + 0x3220, 0xA2E5, + 0x3221, 0xA2E6, + 0x3222, 0xA2E7, + 0x3223, 0xA2E8, + 0x3224, 0xA2E9, + 0x3225, 0xA2EA, + 0x3226, 0xA2EB, + 0x3227, 0xA2EC, + 0x3228, 0xA2ED, + 0x3229, 0xA2EE, + 0x4E00, 0xD2BB, + 0x4E01, 0xB6A1, + 0x4E03, 0xC6DF, + 0x4E07, 0xCDF2, + 0x4E08, 0xD5C9, + 0x4E09, 0xC8FD, + 0x4E0A, 0xC9CF, + 0x4E0B, 0xCFC2, + 0x4E0C, 0xD8A2, + 0x4E0D, 0xB2BB, + 0x4E0E, 0xD3EB, + 0x4E10, 0xD8A4, + 0x4E11, 0xB3F3, + 0x4E13, 0xD7A8, + 0x4E14, 0xC7D2, + 0x4E15, 0xD8A7, + 0x4E16, 0xCAC0, + 0x4E18, 0xC7F0, + 0x4E19, 0xB1FB, + 0x4E1A, 0xD2B5, + 0x4E1B, 0xB4D4, + 0x4E1C, 0xB6AB, + 0x4E1D, 0xCBBF, + 0x4E1E, 0xD8A9, + 0x4E22, 0xB6AA, + 0x4E24, 0xC1BD, + 0x4E25, 0xD1CF, + 0x4E27, 0xC9A5, + 0x4E28, 0xD8AD, + 0x4E2A, 0xB8F6, + 0x4E2B, 0xD1BE, + 0x4E2C, 0xE3DC, + 0x4E2D, 0xD6D0, + 0x4E30, 0xB7E1, + 0x4E32, 0xB4AE, + 0x4E34, 0xC1D9, + 0x4E36, 0xD8BC, + 0x4E38, 0xCDE8, + 0x4E39, 0xB5A4, + 0x4E3A, 0xCEAA, + 0x4E3B, 0xD6F7, + 0x4E3D, 0xC0F6, + 0x4E3E, 0xBED9, + 0x4E3F, 0xD8AF, + 0x4E43, 0xC4CB, + 0x4E45, 0xBEC3, + 0x4E47, 0xD8B1, + 0x4E48, 0xC3B4, + 0x4E49, 0xD2E5, + 0x4E4B, 0xD6AE, + 0x4E4C, 0xCEDA, + 0x4E4D, 0xD5A7, + 0x4E4E, 0xBAF5, + 0x4E4F, 0xB7A6, + 0x4E50, 0xC0D6, + 0x4E52, 0xC6B9, + 0x4E53, 0xC5D2, + 0x4E54, 0xC7C7, + 0x4E56, 0xB9D4, + 0x4E58, 0xB3CB, + 0x4E59, 0xD2D2, + 0x4E5C, 0xD8BF, + 0x4E5D, 0xBEC5, + 0x4E5E, 0xC6F2, + 0x4E5F, 0xD2B2, + 0x4E60, 0xCFB0, + 0x4E61, 0xCFE7, + 0x4E66, 0xCAE9, + 0x4E69, 0xD8C0, + 0x4E70, 0xC2F2, + 0x4E71, 0xC2D2, + 0x4E73, 0xC8E9, + 0x4E7E, 0xC7AC, + 0x4E86, 0xC1CB, + 0x4E88, 0xD3E8, + 0x4E89, 0xD5F9, + 0x4E8B, 0xCAC2, + 0x4E8C, 0xB6FE, + 0x4E8D, 0xD8A1, + 0x4E8E, 0xD3DA, + 0x4E8F, 0xBFF7, + 0x4E91, 0xD4C6, + 0x4E92, 0xBBA5, + 0x4E93, 0xD8C1, + 0x4E94, 0xCEE5, + 0x4E95, 0xBEAE, + 0x4E98, 0xD8A8, + 0x4E9A, 0xD1C7, + 0x4E9B, 0xD0A9, + 0x4E9F, 0xD8BD, + 0x4EA0, 0xD9EF, + 0x4EA1, 0xCDF6, + 0x4EA2, 0xBFBA, + 0x4EA4, 0xBDBB, + 0x4EA5, 0xBAA5, + 0x4EA6, 0xD2E0, + 0x4EA7, 0xB2FA, + 0x4EA8, 0xBAE0, + 0x4EA9, 0xC4B6, + 0x4EAB, 0xCFED, + 0x4EAC, 0xBEA9, + 0x4EAD, 0xCDA4, + 0x4EAE, 0xC1C1, + 0x4EB2, 0xC7D7, + 0x4EB3, 0xD9F1, + 0x4EB5, 0xD9F4, + 0x4EBA, 0xC8CB, + 0x4EBB, 0xD8E9, + 0x4EBF, 0xD2DA, + 0x4EC0, 0xCAB2, + 0x4EC1, 0xC8CA, + 0x4EC2, 0xD8EC, + 0x4EC3, 0xD8EA, + 0x4EC4, 0xD8C6, + 0x4EC5, 0xBDF6, + 0x4EC6, 0xC6CD, + 0x4EC7, 0xB3F0, + 0x4EC9, 0xD8EB, + 0x4ECA, 0xBDF1, + 0x4ECB, 0xBDE9, + 0x4ECD, 0xC8D4, + 0x4ECE, 0xB4D3, + 0x4ED1, 0xC2D8, + 0x4ED3, 0xB2D6, + 0x4ED4, 0xD7D0, + 0x4ED5, 0xCACB, + 0x4ED6, 0xCBFB, + 0x4ED7, 0xD5CC, + 0x4ED8, 0xB8B6, + 0x4ED9, 0xCFC9, + 0x4EDD, 0xD9DA, + 0x4EDE, 0xD8F0, + 0x4EDF, 0xC7AA, + 0x4EE1, 0xD8EE, + 0x4EE3, 0xB4FA, + 0x4EE4, 0xC1EE, + 0x4EE5, 0xD2D4, + 0x4EE8, 0xD8ED, + 0x4EEA, 0xD2C7, + 0x4EEB, 0xD8EF, + 0x4EEC, 0xC3C7, + 0x4EF0, 0xD1F6, + 0x4EF2, 0xD6D9, + 0x4EF3, 0xD8F2, + 0x4EF5, 0xD8F5, + 0x4EF6, 0xBCFE, + 0x4EF7, 0xBCDB, + 0x4EFB, 0xC8CE, + 0x4EFD, 0xB7DD, + 0x4EFF, 0xB7C2, + 0x4F01, 0xC6F3, + 0x4F09, 0xD8F8, + 0x4F0A, 0xD2C1, + 0x4F0D, 0xCEE9, + 0x4F0E, 0xBCBF, + 0x4F0F, 0xB7FC, + 0x4F10, 0xB7A5, + 0x4F11, 0xD0DD, + 0x4F17, 0xD6DA, + 0x4F18, 0xD3C5, + 0x4F19, 0xBBEF, + 0x4F1A, 0xBBE1, + 0x4F1B, 0xD8F1, + 0x4F1E, 0xC9A1, + 0x4F1F, 0xCEB0, + 0x4F20, 0xB4AB, + 0x4F22, 0xD8F3, + 0x4F24, 0xC9CB, + 0x4F25, 0xD8F6, + 0x4F26, 0xC2D7, + 0x4F27, 0xD8F7, + 0x4F2A, 0xCEB1, + 0x4F2B, 0xD8F9, + 0x4F2F, 0xB2AE, + 0x4F30, 0xB9C0, + 0x4F32, 0xD9A3, + 0x4F34, 0xB0E9, + 0x4F36, 0xC1E6, + 0x4F38, 0xC9EC, + 0x4F3A, 0xCBC5, + 0x4F3C, 0xCBC6, + 0x4F3D, 0xD9A4, + 0x4F43, 0xB5E8, + 0x4F46, 0xB5AB, + 0x4F4D, 0xCEBB, + 0x4F4E, 0xB5CD, + 0x4F4F, 0xD7A1, + 0x4F50, 0xD7F4, + 0x4F51, 0xD3D3, + 0x4F53, 0xCCE5, + 0x4F55, 0xBACE, + 0x4F57, 0xD9A2, + 0x4F58, 0xD9DC, + 0x4F59, 0xD3E0, + 0x4F5A, 0xD8FD, + 0x4F5B, 0xB7F0, + 0x4F5C, 0xD7F7, + 0x4F5D, 0xD8FE, + 0x4F5E, 0xD8FA, + 0x4F5F, 0xD9A1, + 0x4F60, 0xC4E3, + 0x4F63, 0xD3B6, + 0x4F64, 0xD8F4, + 0x4F65, 0xD9DD, + 0x4F67, 0xD8FB, + 0x4F69, 0xC5E5, + 0x4F6C, 0xC0D0, + 0x4F6F, 0xD1F0, + 0x4F70, 0xB0DB, + 0x4F73, 0xBCD1, + 0x4F74, 0xD9A6, + 0x4F76, 0xD9A5, + 0x4F7B, 0xD9AC, + 0x4F7C, 0xD9AE, + 0x4F7E, 0xD9AB, + 0x4F7F, 0xCAB9, + 0x4F83, 0xD9A9, + 0x4F84, 0xD6B6, + 0x4F88, 0xB3DE, + 0x4F89, 0xD9A8, + 0x4F8B, 0xC0FD, + 0x4F8D, 0xCACC, + 0x4F8F, 0xD9AA, + 0x4F91, 0xD9A7, + 0x4F94, 0xD9B0, + 0x4F97, 0xB6B1, + 0x4F9B, 0xB9A9, + 0x4F9D, 0xD2C0, + 0x4FA0, 0xCFC0, + 0x4FA3, 0xC2C2, + 0x4FA5, 0xBDC4, + 0x4FA6, 0xD5EC, + 0x4FA7, 0xB2E0, + 0x4FA8, 0xC7C8, + 0x4FA9, 0xBFEB, + 0x4FAA, 0xD9AD, + 0x4FAC, 0xD9AF, + 0x4FAE, 0xCEEA, + 0x4FAF, 0xBAEE, + 0x4FB5, 0xC7D6, + 0x4FBF, 0xB1E3, + 0x4FC3, 0xB4D9, + 0x4FC4, 0xB6ED, + 0x4FC5, 0xD9B4, + 0x4FCA, 0xBFA1, + 0x4FCE, 0xD9DE, + 0x4FCF, 0xC7CE, + 0x4FD0, 0xC0FE, + 0x4FD1, 0xD9B8, + 0x4FD7, 0xCBD7, + 0x4FD8, 0xB7FD, + 0x4FDA, 0xD9B5, + 0x4FDC, 0xD9B7, + 0x4FDD, 0xB1A3, + 0x4FDE, 0xD3E1, + 0x4FDF, 0xD9B9, + 0x4FE1, 0xD0C5, + 0x4FE3, 0xD9B6, + 0x4FE6, 0xD9B1, + 0x4FE8, 0xD9B2, + 0x4FE9, 0xC1A9, + 0x4FEA, 0xD9B3, + 0x4FED, 0xBCF3, + 0x4FEE, 0xD0DE, + 0x4FEF, 0xB8A9, + 0x4FF1, 0xBEE3, + 0x4FF3, 0xD9BD, + 0x4FF8, 0xD9BA, + 0x4FFA, 0xB0B3, + 0x4FFE, 0xD9C2, + 0x500C, 0xD9C4, + 0x500D, 0xB1B6, + 0x500F, 0xD9BF, + 0x5012, 0xB5B9, + 0x5014, 0xBEF3, + 0x5018, 0xCCC8, + 0x5019, 0xBAF2, + 0x501A, 0xD2D0, + 0x501C, 0xD9C3, + 0x501F, 0xBDE8, + 0x5021, 0xB3AB, + 0x5025, 0xD9C5, + 0x5026, 0xBEEB, + 0x5028, 0xD9C6, + 0x5029, 0xD9BB, + 0x502A, 0xC4DF, + 0x502C, 0xD9BE, + 0x502D, 0xD9C1, + 0x502E, 0xD9C0, + 0x503A, 0xD5AE, + 0x503C, 0xD6B5, + 0x503E, 0xC7E3, + 0x5043, 0xD9C8, + 0x5047, 0xBCD9, + 0x5048, 0xD9CA, + 0x504C, 0xD9BC, + 0x504E, 0xD9CB, + 0x504F, 0xC6AB, + 0x5055, 0xD9C9, + 0x505A, 0xD7F6, + 0x505C, 0xCDA3, + 0x5065, 0xBDA1, + 0x506C, 0xD9CC, + 0x5076, 0xC5BC, + 0x5077, 0xCDB5, + 0x507B, 0xD9CD, + 0x507E, 0xD9C7, + 0x507F, 0xB3A5, + 0x5080, 0xBFFE, + 0x5085, 0xB8B5, + 0x5088, 0xC0FC, + 0x508D, 0xB0F8, + 0x50A3, 0xB4F6, + 0x50A5, 0xD9CE, + 0x50A7, 0xD9CF, + 0x50A8, 0xB4A2, + 0x50A9, 0xD9D0, + 0x50AC, 0xB4DF, + 0x50B2, 0xB0C1, + 0x50BA, 0xD9D1, + 0x50BB, 0xC9B5, + 0x50CF, 0xCFF1, + 0x50D6, 0xD9D2, + 0x50DA, 0xC1C5, + 0x50E6, 0xD9D6, + 0x50E7, 0xC9AE, + 0x50EC, 0xD9D5, + 0x50ED, 0xD9D4, + 0x50EE, 0xD9D7, + 0x50F3, 0xCBDB, + 0x50F5, 0xBDA9, + 0x50FB, 0xC6A7, + 0x5106, 0xD9D3, + 0x5107, 0xD9D8, + 0x510B, 0xD9D9, + 0x5112, 0xC8E5, + 0x5121, 0xC0DC, + 0x513F, 0xB6F9, + 0x5140, 0xD8A3, + 0x5141, 0xD4CA, + 0x5143, 0xD4AA, + 0x5144, 0xD0D6, + 0x5145, 0xB3E4, + 0x5146, 0xD5D7, + 0x5148, 0xCFC8, + 0x5149, 0xB9E2, + 0x514B, 0xBFCB, + 0x514D, 0xC3E2, + 0x5151, 0xB6D2, + 0x5154, 0xCDC3, + 0x5155, 0xD9EE, + 0x5156, 0xD9F0, + 0x515A, 0xB5B3, + 0x515C, 0xB6B5, + 0x5162, 0xBEA4, + 0x5165, 0xC8EB, + 0x5168, 0xC8AB, + 0x516B, 0xB0CB, + 0x516C, 0xB9AB, + 0x516D, 0xC1F9, + 0x516E, 0xD9E2, + 0x5170, 0xC0BC, + 0x5171, 0xB9B2, + 0x5173, 0xB9D8, + 0x5174, 0xD0CB, + 0x5175, 0xB1F8, + 0x5176, 0xC6E4, + 0x5177, 0xBEDF, + 0x5178, 0xB5E4, + 0x5179, 0xD7C8, + 0x517B, 0xD1F8, + 0x517C, 0xBCE6, + 0x517D, 0xCADE, + 0x5180, 0xBCBD, + 0x5181, 0xD9E6, + 0x5182, 0xD8E7, + 0x5185, 0xC4DA, + 0x5188, 0xB8D4, + 0x5189, 0xC8BD, + 0x518C, 0xB2E1, + 0x518D, 0xD4D9, + 0x5192, 0xC3B0, + 0x5195, 0xC3E1, + 0x5196, 0xDAA2, + 0x5197, 0xC8DF, + 0x5199, 0xD0B4, + 0x519B, 0xBEFC, + 0x519C, 0xC5A9, + 0x51A0, 0xB9DA, + 0x51A2, 0xDAA3, + 0x51A4, 0xD4A9, + 0x51A5, 0xDAA4, + 0x51AB, 0xD9FB, + 0x51AC, 0xB6AC, + 0x51AF, 0xB7EB, + 0x51B0, 0xB1F9, + 0x51B1, 0xD9FC, + 0x51B2, 0xB3E5, + 0x51B3, 0xBEF6, + 0x51B5, 0xBFF6, + 0x51B6, 0xD2B1, + 0x51B7, 0xC0E4, + 0x51BB, 0xB6B3, + 0x51BC, 0xD9FE, + 0x51BD, 0xD9FD, + 0x51C0, 0xBEBB, + 0x51C4, 0xC6E0, + 0x51C6, 0xD7BC, + 0x51C7, 0xDAA1, + 0x51C9, 0xC1B9, + 0x51CB, 0xB5F2, + 0x51CC, 0xC1E8, + 0x51CF, 0xBCF5, + 0x51D1, 0xB4D5, + 0x51DB, 0xC1DD, + 0x51DD, 0xC4FD, + 0x51E0, 0xBCB8, + 0x51E1, 0xB7B2, + 0x51E4, 0xB7EF, + 0x51EB, 0xD9EC, + 0x51ED, 0xC6BE, + 0x51EF, 0xBFAD, + 0x51F0, 0xBBCB, + 0x51F3, 0xB5CA, + 0x51F5, 0xDBC9, + 0x51F6, 0xD0D7, + 0x51F8, 0xCDB9, + 0x51F9, 0xB0BC, + 0x51FA, 0xB3F6, + 0x51FB, 0xBBF7, + 0x51FC, 0xDBCA, + 0x51FD, 0xBAAF, + 0x51FF, 0xD4E4, + 0x5200, 0xB5B6, + 0x5201, 0xB5F3, + 0x5202, 0xD8D6, + 0x5203, 0xC8D0, + 0x5206, 0xB7D6, + 0x5207, 0xC7D0, + 0x5208, 0xD8D7, + 0x520A, 0xBFAF, + 0x520D, 0xDBBB, + 0x520E, 0xD8D8, + 0x5211, 0xD0CC, + 0x5212, 0xBBAE, + 0x5216, 0xEBBE, + 0x5217, 0xC1D0, + 0x5218, 0xC1F5, + 0x5219, 0xD4F2, + 0x521A, 0xB8D5, + 0x521B, 0xB4B4, + 0x521D, 0xB3F5, + 0x5220, 0xC9BE, + 0x5224, 0xC5D0, + 0x5228, 0xC5D9, + 0x5229, 0xC0FB, + 0x522B, 0xB1F0, + 0x522D, 0xD8D9, + 0x522E, 0xB9CE, + 0x5230, 0xB5BD, + 0x5233, 0xD8DA, + 0x5236, 0xD6C6, + 0x5237, 0xCBA2, + 0x5238, 0xC8AF, + 0x5239, 0xC9B2, + 0x523A, 0xB4CC, + 0x523B, 0xBFCC, + 0x523D, 0xB9F4, + 0x523F, 0xD8DB, + 0x5240, 0xD8DC, + 0x5241, 0xB6E7, + 0x5242, 0xBCC1, + 0x5243, 0xCCEA, + 0x524A, 0xCFF7, + 0x524C, 0xD8DD, + 0x524D, 0xC7B0, + 0x5250, 0xB9D0, + 0x5251, 0xBDA3, + 0x5254, 0xCCDE, + 0x5256, 0xC6CA, + 0x525C, 0xD8E0, + 0x525E, 0xD8DE, + 0x5261, 0xD8DF, + 0x5265, 0xB0FE, + 0x5267, 0xBEE7, + 0x5269, 0xCAA3, + 0x526A, 0xBCF4, + 0x526F, 0xB8B1, + 0x5272, 0xB8EE, + 0x527D, 0xD8E2, + 0x527F, 0xBDCB, + 0x5281, 0xD8E4, + 0x5282, 0xD8E3, + 0x5288, 0xC5FC, + 0x5290, 0xD8E5, + 0x5293, 0xD8E6, + 0x529B, 0xC1A6, + 0x529D, 0xC8B0, + 0x529E, 0xB0EC, + 0x529F, 0xB9A6, + 0x52A0, 0xBCD3, + 0x52A1, 0xCEF1, + 0x52A2, 0xDBBD, + 0x52A3, 0xC1D3, + 0x52A8, 0xB6AF, + 0x52A9, 0xD6FA, + 0x52AA, 0xC5AC, + 0x52AB, 0xBDD9, + 0x52AC, 0xDBBE, + 0x52AD, 0xDBBF, + 0x52B1, 0xC0F8, + 0x52B2, 0xBEA2, + 0x52B3, 0xC0CD, + 0x52BE, 0xDBC0, + 0x52BF, 0xCAC6, + 0x52C3, 0xB2AA, + 0x52C7, 0xD3C2, + 0x52C9, 0xC3E3, + 0x52CB, 0xD1AB, + 0x52D0, 0xDBC2, + 0x52D2, 0xC0D5, + 0x52D6, 0xDBC3, + 0x52D8, 0xBFB1, + 0x52DF, 0xC4BC, + 0x52E4, 0xC7DA, + 0x52F0, 0xDBC4, + 0x52F9, 0xD9E8, + 0x52FA, 0xC9D7, + 0x52FE, 0xB9B4, + 0x52FF, 0xCEF0, + 0x5300, 0xD4C8, + 0x5305, 0xB0FC, + 0x5306, 0xB4D2, + 0x5308, 0xD0D9, + 0x530D, 0xD9E9, + 0x530F, 0xDECB, + 0x5310, 0xD9EB, + 0x5315, 0xD8B0, + 0x5316, 0xBBAF, + 0x5317, 0xB1B1, + 0x5319, 0xB3D7, + 0x531A, 0xD8CE, + 0x531D, 0xD4D1, + 0x5320, 0xBDB3, + 0x5321, 0xBFEF, + 0x5323, 0xCFBB, + 0x5326, 0xD8D0, + 0x532A, 0xB7CB, + 0x532E, 0xD8D1, + 0x5339, 0xC6A5, + 0x533A, 0xC7F8, + 0x533B, 0xD2BD, + 0x533E, 0xD8D2, + 0x533F, 0xC4E4, + 0x5341, 0xCAAE, + 0x5343, 0xC7A7, + 0x5345, 0xD8A6, + 0x5347, 0xC9FD, + 0x5348, 0xCEE7, + 0x5349, 0xBBDC, + 0x534A, 0xB0EB, + 0x534E, 0xBBAA, + 0x534F, 0xD0AD, + 0x5351, 0xB1B0, + 0x5352, 0xD7E4, + 0x5353, 0xD7BF, + 0x5355, 0xB5A5, + 0x5356, 0xC2F4, + 0x5357, 0xC4CF, + 0x535A, 0xB2A9, + 0x535C, 0xB2B7, + 0x535E, 0xB1E5, + 0x535F, 0xDFB2, + 0x5360, 0xD5BC, + 0x5361, 0xBFA8, + 0x5362, 0xC2AC, + 0x5363, 0xD8D5, + 0x5364, 0xC2B1, + 0x5366, 0xD8D4, + 0x5367, 0xCED4, + 0x5369, 0xDAE0, + 0x536B, 0xCEC0, + 0x536E, 0xD8B4, + 0x536F, 0xC3AE, + 0x5370, 0xD3A1, + 0x5371, 0xCEA3, + 0x5373, 0xBCB4, + 0x5374, 0xC8B4, + 0x5375, 0xC2D1, + 0x5377, 0xBEED, + 0x5378, 0xD0B6, + 0x537A, 0xDAE1, + 0x537F, 0xC7E4, + 0x5382, 0xB3A7, + 0x5384, 0xB6F2, + 0x5385, 0xCCFC, + 0x5386, 0xC0FA, + 0x5389, 0xC0F7, + 0x538B, 0xD1B9, + 0x538C, 0xD1E1, + 0x538D, 0xD8C7, + 0x5395, 0xB2DE, + 0x5398, 0xC0E5, + 0x539A, 0xBAF1, + 0x539D, 0xD8C8, + 0x539F, 0xD4AD, + 0x53A2, 0xCFE1, + 0x53A3, 0xD8C9, + 0x53A5, 0xD8CA, + 0x53A6, 0xCFC3, + 0x53A8, 0xB3F8, + 0x53A9, 0xBEC7, + 0x53AE, 0xD8CB, + 0x53B6, 0xDBCC, + 0x53BB, 0xC8A5, + 0x53BF, 0xCFD8, + 0x53C1, 0xC8FE, + 0x53C2, 0xB2CE, + 0x53C8, 0xD3D6, + 0x53C9, 0xB2E6, + 0x53CA, 0xBCB0, + 0x53CB, 0xD3D1, + 0x53CC, 0xCBAB, + 0x53CD, 0xB7B4, + 0x53D1, 0xB7A2, + 0x53D4, 0xCAE5, + 0x53D6, 0xC8A1, + 0x53D7, 0xCADC, + 0x53D8, 0xB1E4, + 0x53D9, 0xD0F0, + 0x53DB, 0xC5D1, + 0x53DF, 0xDBC5, + 0x53E0, 0xB5FE, + 0x53E3, 0xBFDA, + 0x53E4, 0xB9C5, + 0x53E5, 0xBEE4, + 0x53E6, 0xC1ED, + 0x53E8, 0xDFB6, + 0x53E9, 0xDFB5, + 0x53EA, 0xD6BB, + 0x53EB, 0xBDD0, + 0x53EC, 0xD5D9, + 0x53ED, 0xB0C8, + 0x53EE, 0xB6A3, + 0x53EF, 0xBFC9, + 0x53F0, 0xCCA8, + 0x53F1, 0xDFB3, + 0x53F2, 0xCAB7, + 0x53F3, 0xD3D2, + 0x53F5, 0xD8CF, + 0x53F6, 0xD2B6, + 0x53F7, 0xBAC5, + 0x53F8, 0xCBBE, + 0x53F9, 0xCCBE, + 0x53FB, 0xDFB7, + 0x53FC, 0xB5F0, + 0x53FD, 0xDFB4, + 0x5401, 0xD3F5, + 0x5403, 0xB3D4, + 0x5404, 0xB8F7, + 0x5406, 0xDFBA, + 0x5408, 0xBACF, + 0x5409, 0xBCAA, + 0x540A, 0xB5F5, + 0x540C, 0xCDAC, + 0x540D, 0xC3FB, + 0x540E, 0xBAF3, + 0x540F, 0xC0F4, + 0x5410, 0xCDC2, + 0x5411, 0xCFF2, + 0x5412, 0xDFB8, + 0x5413, 0xCFC5, + 0x5415, 0xC2C0, + 0x5416, 0xDFB9, + 0x5417, 0xC2F0, + 0x541B, 0xBEFD, + 0x541D, 0xC1DF, + 0x541E, 0xCDCC, + 0x541F, 0xD2F7, + 0x5420, 0xB7CD, + 0x5421, 0xDFC1, + 0x5423, 0xDFC4, + 0x5426, 0xB7F1, + 0x5427, 0xB0C9, + 0x5428, 0xB6D6, + 0x5429, 0xB7D4, + 0x542B, 0xBAAC, + 0x542C, 0xCCFD, + 0x542D, 0xBFD4, + 0x542E, 0xCBB1, + 0x542F, 0xC6F4, + 0x5431, 0xD6A8, + 0x5432, 0xDFC5, + 0x5434, 0xCEE2, + 0x5435, 0xB3B3, + 0x5438, 0xCEFC, + 0x5439, 0xB4B5, + 0x543B, 0xCEC7, + 0x543C, 0xBAF0, + 0x543E, 0xCEE1, + 0x5440, 0xD1BD, + 0x5443, 0xDFC0, + 0x5446, 0xB4F4, + 0x5448, 0xB3CA, + 0x544A, 0xB8E6, + 0x544B, 0xDFBB, + 0x5450, 0xC4C5, + 0x5452, 0xDFBC, + 0x5453, 0xDFBD, + 0x5454, 0xDFBE, + 0x5455, 0xC5BB, + 0x5456, 0xDFBF, + 0x5457, 0xDFC2, + 0x5458, 0xD4B1, + 0x5459, 0xDFC3, + 0x545B, 0xC7BA, + 0x545C, 0xCED8, + 0x5462, 0xC4D8, + 0x5464, 0xDFCA, + 0x5466, 0xDFCF, + 0x5468, 0xD6DC, + 0x5471, 0xDFC9, + 0x5472, 0xDFDA, + 0x5473, 0xCEB6, + 0x5475, 0xBAC7, + 0x5476, 0xDFCE, + 0x5477, 0xDFC8, + 0x5478, 0xC5DE, + 0x547B, 0xC9EB, + 0x547C, 0xBAF4, + 0x547D, 0xC3FC, + 0x5480, 0xBED7, + 0x5482, 0xDFC6, + 0x5484, 0xDFCD, + 0x5486, 0xC5D8, + 0x548B, 0xD5A6, + 0x548C, 0xBACD, + 0x548E, 0xBECC, + 0x548F, 0xD3BD, + 0x5490, 0xB8C0, + 0x5492, 0xD6E4, + 0x5494, 0xDFC7, + 0x5495, 0xB9BE, + 0x5496, 0xBFA7, + 0x5499, 0xC1FC, + 0x549A, 0xDFCB, + 0x549B, 0xDFCC, + 0x549D, 0xDFD0, + 0x54A3, 0xDFDB, + 0x54A4, 0xDFE5, + 0x54A6, 0xDFD7, + 0x54A7, 0xDFD6, + 0x54A8, 0xD7C9, + 0x54A9, 0xDFE3, + 0x54AA, 0xDFE4, + 0x54AB, 0xE5EB, + 0x54AC, 0xD2A7, + 0x54AD, 0xDFD2, + 0x54AF, 0xBFA9, + 0x54B1, 0xD4DB, + 0x54B3, 0xBFC8, + 0x54B4, 0xDFD4, + 0x54B8, 0xCFCC, + 0x54BB, 0xDFDD, + 0x54BD, 0xD1CA, + 0x54BF, 0xDFDE, + 0x54C0, 0xB0A7, + 0x54C1, 0xC6B7, + 0x54C2, 0xDFD3, + 0x54C4, 0xBAE5, + 0x54C6, 0xB6DF, + 0x54C7, 0xCDDB, + 0x54C8, 0xB9FE, + 0x54C9, 0xD4D5, + 0x54CC, 0xDFDF, + 0x54CD, 0xCFEC, + 0x54CE, 0xB0A5, + 0x54CF, 0xDFE7, + 0x54D0, 0xDFD1, + 0x54D1, 0xD1C6, + 0x54D2, 0xDFD5, + 0x54D3, 0xDFD8, + 0x54D4, 0xDFD9, + 0x54D5, 0xDFDC, + 0x54D7, 0xBBA9, + 0x54D9, 0xDFE0, + 0x54DA, 0xDFE1, + 0x54DC, 0xDFE2, + 0x54DD, 0xDFE6, + 0x54DE, 0xDFE8, + 0x54DF, 0xD3B4, + 0x54E5, 0xB8E7, + 0x54E6, 0xC5B6, + 0x54E7, 0xDFEA, + 0x54E8, 0xC9DA, + 0x54E9, 0xC1A8, + 0x54EA, 0xC4C4, + 0x54ED, 0xBFDE, + 0x54EE, 0xCFF8, + 0x54F2, 0xD5DC, + 0x54F3, 0xDFEE, + 0x54FA, 0xB2B8, + 0x54FC, 0xBADF, + 0x54FD, 0xDFEC, + 0x54FF, 0xDBC1, + 0x5501, 0xD1E4, + 0x5506, 0xCBF4, + 0x5507, 0xB4BD, + 0x5509, 0xB0A6, + 0x550F, 0xDFF1, + 0x5510, 0xCCC6, + 0x5511, 0xDFF2, + 0x5514, 0xDFED, + 0x551B, 0xDFE9, + 0x5520, 0xDFEB, + 0x5522, 0xDFEF, + 0x5523, 0xDFF0, + 0x5524, 0xBBBD, + 0x5527, 0xDFF3, + 0x552A, 0xDFF4, + 0x552C, 0xBBA3, + 0x552E, 0xCADB, + 0x552F, 0xCEA8, + 0x5530, 0xE0A7, + 0x5531, 0xB3AA, + 0x5533, 0xE0A6, + 0x5537, 0xE0A1, + 0x553C, 0xDFFE, + 0x553E, 0xCDD9, + 0x553F, 0xDFFC, + 0x5541, 0xDFFA, + 0x5543, 0xBFD0, + 0x5544, 0xD7C4, + 0x5546, 0xC9CC, + 0x5549, 0xDFF8, + 0x554A, 0xB0A1, + 0x5550, 0xDFFD, + 0x5555, 0xDFFB, + 0x5556, 0xE0A2, + 0x555C, 0xE0A8, + 0x5561, 0xB7C8, + 0x5564, 0xC6A1, + 0x5565, 0xC9B6, + 0x5566, 0xC0B2, + 0x5567, 0xDFF5, + 0x556A, 0xC5BE, + 0x556C, 0xD8C4, + 0x556D, 0xDFF9, + 0x556E, 0xC4F6, + 0x5575, 0xE0A3, + 0x5576, 0xE0A4, + 0x5577, 0xE0A5, + 0x5578, 0xD0A5, + 0x557B, 0xE0B4, + 0x557C, 0xCCE4, + 0x557E, 0xE0B1, + 0x5580, 0xBFA6, + 0x5581, 0xE0AF, + 0x5582, 0xCEB9, + 0x5583, 0xE0AB, + 0x5584, 0xC9C6, + 0x5587, 0xC0AE, + 0x5588, 0xE0AE, + 0x5589, 0xBAED, + 0x558A, 0xBAB0, + 0x558B, 0xE0A9, + 0x558F, 0xDFF6, + 0x5591, 0xE0B3, + 0x5594, 0xE0B8, + 0x5598, 0xB4AD, + 0x5599, 0xE0B9, + 0x559C, 0xCFB2, + 0x559D, 0xBAC8, + 0x559F, 0xE0B0, + 0x55A7, 0xD0FA, + 0x55B1, 0xE0AC, + 0x55B3, 0xD4FB, + 0x55B5, 0xDFF7, + 0x55B7, 0xC5E7, + 0x55B9, 0xE0AD, + 0x55BB, 0xD3F7, + 0x55BD, 0xE0B6, + 0x55BE, 0xE0B7, + 0x55C4, 0xE0C4, + 0x55C5, 0xD0E1, + 0x55C9, 0xE0BC, + 0x55CC, 0xE0C9, + 0x55CD, 0xE0CA, + 0x55D1, 0xE0BE, + 0x55D2, 0xE0AA, + 0x55D3, 0xC9A4, + 0x55D4, 0xE0C1, + 0x55D6, 0xE0B2, + 0x55DC, 0xCAC8, + 0x55DD, 0xE0C3, + 0x55DF, 0xE0B5, + 0x55E1, 0xCECB, + 0x55E3, 0xCBC3, + 0x55E4, 0xE0CD, + 0x55E5, 0xE0C6, + 0x55E6, 0xE0C2, + 0x55E8, 0xE0CB, + 0x55EA, 0xE0BA, + 0x55EB, 0xE0BF, + 0x55EC, 0xE0C0, + 0x55EF, 0xE0C5, + 0x55F2, 0xE0C7, + 0x55F3, 0xE0C8, + 0x55F5, 0xE0CC, + 0x55F7, 0xE0BB, + 0x55FD, 0xCBD4, + 0x55FE, 0xE0D5, + 0x5600, 0xE0D6, + 0x5601, 0xE0D2, + 0x5608, 0xE0D0, + 0x5609, 0xBCCE, + 0x560C, 0xE0D1, + 0x560E, 0xB8C2, + 0x560F, 0xD8C5, + 0x5618, 0xD0EA, + 0x561B, 0xC2EF, + 0x561E, 0xE0CF, + 0x561F, 0xE0BD, + 0x5623, 0xE0D4, + 0x5624, 0xE0D3, + 0x5627, 0xE0D7, + 0x562C, 0xE0DC, + 0x562D, 0xE0D8, + 0x5631, 0xD6F6, + 0x5632, 0xB3B0, + 0x5634, 0xD7EC, + 0x5636, 0xCBBB, + 0x5639, 0xE0DA, + 0x563B, 0xCEFB, + 0x563F, 0xBAD9, + 0x564C, 0xE0E1, + 0x564D, 0xE0DD, + 0x564E, 0xD2AD, + 0x5654, 0xE0E2, + 0x5657, 0xE0DB, + 0x5658, 0xE0D9, + 0x5659, 0xE0DF, + 0x565C, 0xE0E0, + 0x5662, 0xE0DE, + 0x5664, 0xE0E4, + 0x5668, 0xC6F7, + 0x5669, 0xD8AC, + 0x566A, 0xD4EB, + 0x566B, 0xE0E6, + 0x566C, 0xCAC9, + 0x5671, 0xE0E5, + 0x5676, 0xB8C1, + 0x567B, 0xE0E7, + 0x567C, 0xE0E8, + 0x5685, 0xE0E9, + 0x5686, 0xE0E3, + 0x568E, 0xBABF, + 0x568F, 0xCCE7, + 0x5693, 0xE0EA, + 0x56A3, 0xCFF9, + 0x56AF, 0xE0EB, + 0x56B7, 0xC8C2, + 0x56BC, 0xBDC0, + 0x56CA, 0xC4D2, + 0x56D4, 0xE0EC, + 0x56D7, 0xE0ED, + 0x56DA, 0xC7F4, + 0x56DB, 0xCBC4, + 0x56DD, 0xE0EE, + 0x56DE, 0xBBD8, + 0x56DF, 0xD8B6, + 0x56E0, 0xD2F2, + 0x56E1, 0xE0EF, + 0x56E2, 0xCDC5, + 0x56E4, 0xB6DA, + 0x56EB, 0xE0F1, + 0x56ED, 0xD4B0, + 0x56F0, 0xC0A7, + 0x56F1, 0xB4D1, + 0x56F4, 0xCEA7, + 0x56F5, 0xE0F0, + 0x56F9, 0xE0F2, + 0x56FA, 0xB9CC, + 0x56FD, 0xB9FA, + 0x56FE, 0xCDBC, + 0x56FF, 0xE0F3, + 0x5703, 0xC6D4, + 0x5704, 0xE0F4, + 0x5706, 0xD4B2, + 0x5708, 0xC8A6, + 0x5709, 0xE0F6, + 0x570A, 0xE0F5, + 0x571C, 0xE0F7, + 0x571F, 0xCDC1, + 0x5723, 0xCAA5, + 0x5728, 0xD4DA, + 0x5729, 0xDBD7, + 0x572A, 0xDBD9, + 0x572C, 0xDBD8, + 0x572D, 0xB9E7, + 0x572E, 0xDBDC, + 0x572F, 0xDBDD, + 0x5730, 0xB5D8, + 0x5733, 0xDBDA, + 0x5739, 0xDBDB, + 0x573A, 0xB3A1, + 0x573B, 0xDBDF, + 0x573E, 0xBBF8, + 0x5740, 0xD6B7, + 0x5742, 0xDBE0, + 0x5747, 0xBEF9, + 0x574A, 0xB7BB, + 0x574C, 0xDBD0, + 0x574D, 0xCCAE, + 0x574E, 0xBFB2, + 0x574F, 0xBBB5, + 0x5750, 0xD7F8, + 0x5751, 0xBFD3, + 0x5757, 0xBFE9, + 0x575A, 0xBCE1, + 0x575B, 0xCCB3, + 0x575C, 0xDBDE, + 0x575D, 0xB0D3, + 0x575E, 0xCEEB, + 0x575F, 0xB7D8, + 0x5760, 0xD7B9, + 0x5761, 0xC6C2, + 0x5764, 0xC0A4, + 0x5766, 0xCCB9, + 0x5768, 0xDBE7, + 0x5769, 0xDBE1, + 0x576A, 0xC6BA, + 0x576B, 0xDBE3, + 0x576D, 0xDBE8, + 0x576F, 0xC5F7, + 0x5773, 0xDBEA, + 0x5776, 0xDBE9, + 0x5777, 0xBFC0, + 0x577B, 0xDBE6, + 0x577C, 0xDBE5, + 0x5782, 0xB4B9, + 0x5783, 0xC0AC, + 0x5784, 0xC2A2, + 0x5785, 0xDBE2, + 0x5786, 0xDBE4, + 0x578B, 0xD0CD, + 0x578C, 0xDBED, + 0x5792, 0xC0DD, + 0x5793, 0xDBF2, + 0x579B, 0xB6E2, + 0x57A0, 0xDBF3, + 0x57A1, 0xDBD2, + 0x57A2, 0xB9B8, + 0x57A3, 0xD4AB, + 0x57A4, 0xDBEC, + 0x57A6, 0xBFD1, + 0x57A7, 0xDBF0, + 0x57A9, 0xDBD1, + 0x57AB, 0xB5E6, + 0x57AD, 0xDBEB, + 0x57AE, 0xBFE5, + 0x57B2, 0xDBEE, + 0x57B4, 0xDBF1, + 0x57B8, 0xDBF9, + 0x57C2, 0xB9A1, + 0x57C3, 0xB0A3, + 0x57CB, 0xC2F1, + 0x57CE, 0xB3C7, + 0x57CF, 0xDBEF, + 0x57D2, 0xDBF8, + 0x57D4, 0xC6D2, + 0x57D5, 0xDBF4, + 0x57D8, 0xDBF5, + 0x57D9, 0xDBF7, + 0x57DA, 0xDBF6, + 0x57DD, 0xDBFE, + 0x57DF, 0xD3F2, + 0x57E0, 0xB2BA, + 0x57E4, 0xDBFD, + 0x57ED, 0xDCA4, + 0x57EF, 0xDBFB, + 0x57F4, 0xDBFA, + 0x57F8, 0xDBFC, + 0x57F9, 0xC5E0, + 0x57FA, 0xBBF9, + 0x57FD, 0xDCA3, + 0x5800, 0xDCA5, + 0x5802, 0xCCC3, + 0x5806, 0xB6D1, + 0x5807, 0xDDC0, + 0x580B, 0xDCA1, + 0x580D, 0xDCA2, + 0x5811, 0xC7B5, + 0x5815, 0xB6E9, + 0x5819, 0xDCA7, + 0x581E, 0xDCA6, + 0x5820, 0xDCA9, + 0x5821, 0xB1A4, + 0x5824, 0xB5CC, + 0x582A, 0xBFB0, + 0x5830, 0xD1DF, + 0x5835, 0xB6C2, + 0x5844, 0xDCA8, + 0x584C, 0xCBFA, + 0x584D, 0xEBF3, + 0x5851, 0xCBDC, + 0x5854, 0xCBFE, + 0x5858, 0xCCC1, + 0x585E, 0xC8FB, + 0x5865, 0xDCAA, + 0x586B, 0xCCEE, + 0x586C, 0xDCAB, + 0x587E, 0xDBD3, + 0x5880, 0xDCAF, + 0x5881, 0xDCAC, + 0x5883, 0xBEB3, + 0x5885, 0xCAFB, + 0x5889, 0xDCAD, + 0x5892, 0xC9CA, + 0x5893, 0xC4B9, + 0x5899, 0xC7BD, + 0x589A, 0xDCAE, + 0x589E, 0xD4F6, + 0x589F, 0xD0E6, + 0x58A8, 0xC4AB, + 0x58A9, 0xB6D5, + 0x58BC, 0xDBD4, + 0x58C1, 0xB1DA, + 0x58C5, 0xDBD5, + 0x58D1, 0xDBD6, + 0x58D5, 0xBABE, + 0x58E4, 0xC8C0, + 0x58EB, 0xCABF, + 0x58EC, 0xC8C9, + 0x58EE, 0xD7B3, + 0x58F0, 0xC9F9, + 0x58F3, 0xBFC7, + 0x58F6, 0xBAF8, + 0x58F9, 0xD2BC, + 0x5902, 0xE2BA, + 0x5904, 0xB4A6, + 0x5907, 0xB1B8, + 0x590D, 0xB8B4, + 0x590F, 0xCFC4, + 0x5914, 0xD9E7, + 0x5915, 0xCFA6, + 0x5916, 0xCDE2, + 0x5919, 0xD9ED, + 0x591A, 0xB6E0, + 0x591C, 0xD2B9, + 0x591F, 0xB9BB, + 0x5924, 0xE2B9, + 0x5925, 0xE2B7, + 0x5927, 0xB4F3, + 0x5929, 0xCCEC, + 0x592A, 0xCCAB, + 0x592B, 0xB7F2, + 0x592D, 0xD8B2, + 0x592E, 0xD1EB, + 0x592F, 0xBABB, + 0x5931, 0xCAA7, + 0x5934, 0xCDB7, + 0x5937, 0xD2C4, + 0x5938, 0xBFE4, + 0x5939, 0xBCD0, + 0x593A, 0xB6E1, + 0x593C, 0xDEC5, + 0x5941, 0xDEC6, + 0x5942, 0xDBBC, + 0x5944, 0xD1D9, + 0x5947, 0xC6E6, + 0x5948, 0xC4CE, + 0x5949, 0xB7EE, + 0x594B, 0xB7DC, + 0x594E, 0xBFFC, + 0x594F, 0xD7E0, + 0x5951, 0xC6F5, + 0x5954, 0xB1BC, + 0x5955, 0xDEC8, + 0x5956, 0xBDB1, + 0x5957, 0xCCD7, + 0x5958, 0xDECA, + 0x595A, 0xDEC9, + 0x5960, 0xB5EC, + 0x5962, 0xC9DD, + 0x5965, 0xB0C2, + 0x5973, 0xC5AE, + 0x5974, 0xC5AB, + 0x5976, 0xC4CC, + 0x5978, 0xBCE9, + 0x5979, 0xCBFD, + 0x597D, 0xBAC3, + 0x5981, 0xE5F9, + 0x5982, 0xC8E7, + 0x5983, 0xE5FA, + 0x5984, 0xCDFD, + 0x5986, 0xD7B1, + 0x5987, 0xB8BE, + 0x5988, 0xC2E8, + 0x598A, 0xC8D1, + 0x598D, 0xE5FB, + 0x5992, 0xB6CA, + 0x5993, 0xBCCB, + 0x5996, 0xD1FD, + 0x5997, 0xE6A1, + 0x5999, 0xC3EE, + 0x599E, 0xE6A4, + 0x59A3, 0xE5FE, + 0x59A4, 0xE6A5, + 0x59A5, 0xCDD7, + 0x59A8, 0xB7C1, + 0x59A9, 0xE5FC, + 0x59AA, 0xE5FD, + 0x59AB, 0xE6A3, + 0x59AE, 0xC4DD, + 0x59AF, 0xE6A8, + 0x59B2, 0xE6A7, + 0x59B9, 0xC3C3, + 0x59BB, 0xC6DE, + 0x59BE, 0xE6AA, + 0x59C6, 0xC4B7, + 0x59CA, 0xE6A2, + 0x59CB, 0xCABC, + 0x59D0, 0xBDE3, + 0x59D1, 0xB9C3, + 0x59D2, 0xE6A6, + 0x59D3, 0xD0D5, + 0x59D4, 0xCEAF, + 0x59D7, 0xE6A9, + 0x59D8, 0xE6B0, + 0x59DA, 0xD2A6, + 0x59DC, 0xBDAA, + 0x59DD, 0xE6AD, + 0x59E3, 0xE6AF, + 0x59E5, 0xC0D1, + 0x59E8, 0xD2CC, + 0x59EC, 0xBCA7, + 0x59F9, 0xE6B1, + 0x59FB, 0xD2F6, + 0x59FF, 0xD7CB, + 0x5A01, 0xCDFE, + 0x5A03, 0xCDDE, + 0x5A04, 0xC2A6, + 0x5A05, 0xE6AB, + 0x5A06, 0xE6AC, + 0x5A07, 0xBDBF, + 0x5A08, 0xE6AE, + 0x5A09, 0xE6B3, + 0x5A0C, 0xE6B2, + 0x5A11, 0xE6B6, + 0x5A13, 0xE6B8, + 0x5A18, 0xC4EF, + 0x5A1C, 0xC4C8, + 0x5A1F, 0xBEEA, + 0x5A20, 0xC9EF, + 0x5A23, 0xE6B7, + 0x5A25, 0xB6F0, + 0x5A29, 0xC3E4, + 0x5A31, 0xD3E9, + 0x5A32, 0xE6B4, + 0x5A34, 0xE6B5, + 0x5A36, 0xC8A2, + 0x5A3C, 0xE6BD, + 0x5A40, 0xE6B9, + 0x5A46, 0xC6C5, + 0x5A49, 0xCDF1, + 0x5A4A, 0xE6BB, + 0x5A55, 0xE6BC, + 0x5A5A, 0xBBE9, + 0x5A62, 0xE6BE, + 0x5A67, 0xE6BA, + 0x5A6A, 0xC0B7, + 0x5A74, 0xD3A4, + 0x5A75, 0xE6BF, + 0x5A76, 0xC9F4, + 0x5A77, 0xE6C3, + 0x5A7A, 0xE6C4, + 0x5A7F, 0xD0F6, + 0x5A92, 0xC3BD, + 0x5A9A, 0xC3C4, + 0x5A9B, 0xE6C2, + 0x5AAA, 0xE6C1, + 0x5AB2, 0xE6C7, + 0x5AB3, 0xCFB1, + 0x5AB5, 0xEBF4, + 0x5AB8, 0xE6CA, + 0x5ABE, 0xE6C5, + 0x5AC1, 0xBCDE, + 0x5AC2, 0xC9A9, + 0x5AC9, 0xBCB5, + 0x5ACC, 0xCFD3, + 0x5AD2, 0xE6C8, + 0x5AD4, 0xE6C9, + 0x5AD6, 0xE6CE, + 0x5AD8, 0xE6D0, + 0x5ADC, 0xE6D1, + 0x5AE0, 0xE6CB, + 0x5AE1, 0xB5D5, + 0x5AE3, 0xE6CC, + 0x5AE6, 0xE6CF, + 0x5AE9, 0xC4DB, + 0x5AEB, 0xE6C6, + 0x5AF1, 0xE6CD, + 0x5B09, 0xE6D2, + 0x5B16, 0xE6D4, + 0x5B17, 0xE6D3, + 0x5B32, 0xE6D5, + 0x5B34, 0xD9F8, + 0x5B37, 0xE6D6, + 0x5B40, 0xE6D7, + 0x5B50, 0xD7D3, + 0x5B51, 0xE6DD, + 0x5B53, 0xE6DE, + 0x5B54, 0xBFD7, + 0x5B55, 0xD4D0, + 0x5B57, 0xD7D6, + 0x5B58, 0xB4E6, + 0x5B59, 0xCBEF, + 0x5B5A, 0xE6DA, + 0x5B5B, 0xD8C3, + 0x5B5C, 0xD7CE, + 0x5B5D, 0xD0A2, + 0x5B5F, 0xC3CF, + 0x5B62, 0xE6DF, + 0x5B63, 0xBCBE, + 0x5B64, 0xB9C2, + 0x5B65, 0xE6DB, + 0x5B66, 0xD1A7, + 0x5B69, 0xBAA2, + 0x5B6A, 0xC2CF, + 0x5B6C, 0xD8AB, + 0x5B70, 0xCAEB, + 0x5B71, 0xE5EE, + 0x5B73, 0xE6DC, + 0x5B75, 0xB7F5, + 0x5B7A, 0xC8E6, + 0x5B7D, 0xC4F5, + 0x5B80, 0xE5B2, + 0x5B81, 0xC4FE, + 0x5B83, 0xCBFC, + 0x5B84, 0xE5B3, + 0x5B85, 0xD5AC, + 0x5B87, 0xD3EE, + 0x5B88, 0xCAD8, + 0x5B89, 0xB0B2, + 0x5B8B, 0xCBCE, + 0x5B8C, 0xCDEA, + 0x5B8F, 0xBAEA, + 0x5B93, 0xE5B5, + 0x5B95, 0xE5B4, + 0x5B97, 0xD7DA, + 0x5B98, 0xB9D9, + 0x5B99, 0xD6E6, + 0x5B9A, 0xB6A8, + 0x5B9B, 0xCDF0, + 0x5B9C, 0xD2CB, + 0x5B9D, 0xB1A6, + 0x5B9E, 0xCAB5, + 0x5BA0, 0xB3E8, + 0x5BA1, 0xC9F3, + 0x5BA2, 0xBFCD, + 0x5BA3, 0xD0FB, + 0x5BA4, 0xCAD2, + 0x5BA5, 0xE5B6, + 0x5BA6, 0xBBC2, + 0x5BAA, 0xCFDC, + 0x5BAB, 0xB9AC, + 0x5BB0, 0xD4D7, + 0x5BB3, 0xBAA6, + 0x5BB4, 0xD1E7, + 0x5BB5, 0xCFFC, + 0x5BB6, 0xBCD2, + 0x5BB8, 0xE5B7, + 0x5BB9, 0xC8DD, + 0x5BBD, 0xBFED, + 0x5BBE, 0xB1F6, + 0x5BBF, 0xCBDE, + 0x5BC2, 0xBCC5, + 0x5BC4, 0xBCC4, + 0x5BC5, 0xD2FA, + 0x5BC6, 0xC3DC, + 0x5BC7, 0xBFDC, + 0x5BCC, 0xB8BB, + 0x5BD0, 0xC3C2, + 0x5BD2, 0xBAAE, + 0x5BD3, 0xD4A2, + 0x5BDD, 0xC7DE, + 0x5BDE, 0xC4AF, + 0x5BDF, 0xB2EC, + 0x5BE1, 0xB9D1, + 0x5BE4, 0xE5BB, + 0x5BE5, 0xC1C8, + 0x5BE8, 0xD5AF, + 0x5BEE, 0xE5BC, + 0x5BF0, 0xE5BE, + 0x5BF8, 0xB4E7, + 0x5BF9, 0xB6D4, + 0x5BFA, 0xCBC2, + 0x5BFB, 0xD1B0, + 0x5BFC, 0xB5BC, + 0x5BFF, 0xCAD9, + 0x5C01, 0xB7E2, + 0x5C04, 0xC9E4, + 0x5C06, 0xBDAB, + 0x5C09, 0xCEBE, + 0x5C0A, 0xD7F0, + 0x5C0F, 0xD0A1, + 0x5C11, 0xC9D9, + 0x5C14, 0xB6FB, + 0x5C15, 0xE6D8, + 0x5C16, 0xBCE2, + 0x5C18, 0xB3BE, + 0x5C1A, 0xC9D0, + 0x5C1C, 0xE6D9, + 0x5C1D, 0xB3A2, + 0x5C22, 0xDECC, + 0x5C24, 0xD3C8, + 0x5C25, 0xDECD, + 0x5C27, 0xD2A2, + 0x5C2C, 0xDECE, + 0x5C31, 0xBECD, + 0x5C34, 0xDECF, + 0x5C38, 0xCAAC, + 0x5C39, 0xD2FC, + 0x5C3A, 0xB3DF, + 0x5C3B, 0xE5EA, + 0x5C3C, 0xC4E1, + 0x5C3D, 0xBEA1, + 0x5C3E, 0xCEB2, + 0x5C3F, 0xC4F2, + 0x5C40, 0xBED6, + 0x5C41, 0xC6A8, + 0x5C42, 0xB2E3, + 0x5C45, 0xBED3, + 0x5C48, 0xC7FC, + 0x5C49, 0xCCEB, + 0x5C4A, 0xBDEC, + 0x5C4B, 0xCEDD, + 0x5C4E, 0xCABA, + 0x5C4F, 0xC6C1, + 0x5C50, 0xE5EC, + 0x5C51, 0xD0BC, + 0x5C55, 0xD5B9, + 0x5C59, 0xE5ED, + 0x5C5E, 0xCAF4, + 0x5C60, 0xCDC0, + 0x5C61, 0xC2C5, + 0x5C63, 0xE5EF, + 0x5C65, 0xC2C4, + 0x5C66, 0xE5F0, + 0x5C6E, 0xE5F8, + 0x5C6F, 0xCDCD, + 0x5C71, 0xC9BD, + 0x5C79, 0xD2D9, + 0x5C7A, 0xE1A8, + 0x5C7F, 0xD3EC, + 0x5C81, 0xCBEA, + 0x5C82, 0xC6F1, + 0x5C88, 0xE1AC, + 0x5C8C, 0xE1A7, + 0x5C8D, 0xE1A9, + 0x5C90, 0xE1AA, + 0x5C91, 0xE1AF, + 0x5C94, 0xB2ED, + 0x5C96, 0xE1AB, + 0x5C97, 0xB8DA, + 0x5C98, 0xE1AD, + 0x5C99, 0xE1AE, + 0x5C9A, 0xE1B0, + 0x5C9B, 0xB5BA, + 0x5C9C, 0xE1B1, + 0x5CA2, 0xE1B3, + 0x5CA3, 0xE1B8, + 0x5CA9, 0xD1D2, + 0x5CAB, 0xE1B6, + 0x5CAC, 0xE1B5, + 0x5CAD, 0xC1EB, + 0x5CB1, 0xE1B7, + 0x5CB3, 0xD4C0, + 0x5CB5, 0xE1B2, + 0x5CB7, 0xE1BA, + 0x5CB8, 0xB0B6, + 0x5CBD, 0xE1B4, + 0x5CBF, 0xBFF9, + 0x5CC1, 0xE1B9, + 0x5CC4, 0xE1BB, + 0x5CCB, 0xE1BE, + 0x5CD2, 0xE1BC, + 0x5CD9, 0xD6C5, + 0x5CE1, 0xCFBF, + 0x5CE4, 0xE1BD, + 0x5CE5, 0xE1BF, + 0x5CE6, 0xC2CD, + 0x5CE8, 0xB6EB, + 0x5CEA, 0xD3F8, + 0x5CED, 0xC7CD, + 0x5CF0, 0xB7E5, + 0x5CFB, 0xBEFE, + 0x5D02, 0xE1C0, + 0x5D03, 0xE1C1, + 0x5D06, 0xE1C7, + 0x5D07, 0xB3E7, + 0x5D0E, 0xC6E9, + 0x5D14, 0xB4DE, + 0x5D16, 0xD1C2, + 0x5D1B, 0xE1C8, + 0x5D1E, 0xE1C6, + 0x5D24, 0xE1C5, + 0x5D26, 0xE1C3, + 0x5D27, 0xE1C2, + 0x5D29, 0xB1C0, + 0x5D2D, 0xD5B8, + 0x5D2E, 0xE1C4, + 0x5D34, 0xE1CB, + 0x5D3D, 0xE1CC, + 0x5D3E, 0xE1CA, + 0x5D47, 0xEFFA, + 0x5D4A, 0xE1D3, + 0x5D4B, 0xE1D2, + 0x5D4C, 0xC7B6, + 0x5D58, 0xE1C9, + 0x5D5B, 0xE1CE, + 0x5D5D, 0xE1D0, + 0x5D69, 0xE1D4, + 0x5D6B, 0xE1D1, + 0x5D6C, 0xE1CD, + 0x5D6F, 0xE1CF, + 0x5D74, 0xE1D5, + 0x5D82, 0xE1D6, + 0x5D99, 0xE1D7, + 0x5D9D, 0xE1D8, + 0x5DB7, 0xE1DA, + 0x5DC5, 0xE1DB, + 0x5DCD, 0xCEA1, + 0x5DDB, 0xE7DD, + 0x5DDD, 0xB4A8, + 0x5DDE, 0xD6DD, + 0x5DE1, 0xD1B2, + 0x5DE2, 0xB3B2, + 0x5DE5, 0xB9A4, + 0x5DE6, 0xD7F3, + 0x5DE7, 0xC7C9, + 0x5DE8, 0xBEDE, + 0x5DE9, 0xB9AE, + 0x5DEB, 0xCED7, + 0x5DEE, 0xB2EE, + 0x5DEF, 0xDBCF, + 0x5DF1, 0xBCBA, + 0x5DF2, 0xD2D1, + 0x5DF3, 0xCBC8, + 0x5DF4, 0xB0CD, + 0x5DF7, 0xCFEF, + 0x5DFD, 0xD9E3, + 0x5DFE, 0xBDED, + 0x5E01, 0xB1D2, + 0x5E02, 0xCAD0, + 0x5E03, 0xB2BC, + 0x5E05, 0xCBA7, + 0x5E06, 0xB7AB, + 0x5E08, 0xCAA6, + 0x5E0C, 0xCFA3, + 0x5E0F, 0xE0F8, + 0x5E10, 0xD5CA, + 0x5E11, 0xE0FB, + 0x5E14, 0xE0FA, + 0x5E15, 0xC5C1, + 0x5E16, 0xCCFB, + 0x5E18, 0xC1B1, + 0x5E19, 0xE0F9, + 0x5E1A, 0xD6E3, + 0x5E1B, 0xB2AF, + 0x5E1C, 0xD6C4, + 0x5E1D, 0xB5DB, + 0x5E26, 0xB4F8, + 0x5E27, 0xD6A1, + 0x5E2D, 0xCFAF, + 0x5E2E, 0xB0EF, + 0x5E31, 0xE0FC, + 0x5E37, 0xE1A1, + 0x5E38, 0xB3A3, + 0x5E3B, 0xE0FD, + 0x5E3C, 0xE0FE, + 0x5E3D, 0xC3B1, + 0x5E42, 0xC3DD, + 0x5E44, 0xE1A2, + 0x5E45, 0xB7F9, + 0x5E4C, 0xBBCF, + 0x5E54, 0xE1A3, + 0x5E55, 0xC4BB, + 0x5E5B, 0xE1A4, + 0x5E5E, 0xE1A5, + 0x5E61, 0xE1A6, + 0x5E62, 0xB4B1, + 0x5E72, 0xB8C9, + 0x5E73, 0xC6BD, + 0x5E74, 0xC4EA, + 0x5E76, 0xB2A2, + 0x5E78, 0xD0D2, + 0x5E7A, 0xE7DB, + 0x5E7B, 0xBBC3, + 0x5E7C, 0xD3D7, + 0x5E7D, 0xD3C4, + 0x5E7F, 0xB9E3, + 0x5E80, 0xE2CF, + 0x5E84, 0xD7AF, + 0x5E86, 0xC7EC, + 0x5E87, 0xB1D3, + 0x5E8A, 0xB4B2, + 0x5E8B, 0xE2D1, + 0x5E8F, 0xD0F2, + 0x5E90, 0xC2AE, + 0x5E91, 0xE2D0, + 0x5E93, 0xBFE2, + 0x5E94, 0xD3A6, + 0x5E95, 0xB5D7, + 0x5E96, 0xE2D2, + 0x5E97, 0xB5EA, + 0x5E99, 0xC3ED, + 0x5E9A, 0xB8FD, + 0x5E9C, 0xB8AE, + 0x5E9E, 0xC5D3, + 0x5E9F, 0xB7CF, + 0x5EA0, 0xE2D4, + 0x5EA5, 0xE2D3, + 0x5EA6, 0xB6C8, + 0x5EA7, 0xD7F9, + 0x5EAD, 0xCDA5, + 0x5EB3, 0xE2D8, + 0x5EB5, 0xE2D6, + 0x5EB6, 0xCAFC, + 0x5EB7, 0xBFB5, + 0x5EB8, 0xD3B9, + 0x5EB9, 0xE2D5, + 0x5EBE, 0xE2D7, + 0x5EC9, 0xC1AE, + 0x5ECA, 0xC0C8, + 0x5ED1, 0xE2DB, + 0x5ED2, 0xE2DA, + 0x5ED3, 0xC0AA, + 0x5ED6, 0xC1CE, + 0x5EDB, 0xE2DC, + 0x5EE8, 0xE2DD, + 0x5EEA, 0xE2DE, + 0x5EF4, 0xDBC8, + 0x5EF6, 0xD1D3, + 0x5EF7, 0xCDA2, + 0x5EFA, 0xBDA8, + 0x5EFE, 0xDEC3, + 0x5EFF, 0xD8A5, + 0x5F00, 0xBFAA, + 0x5F01, 0xDBCD, + 0x5F02, 0xD2EC, + 0x5F03, 0xC6FA, + 0x5F04, 0xC5AA, + 0x5F08, 0xDEC4, + 0x5F0A, 0xB1D7, + 0x5F0B, 0xDFAE, + 0x5F0F, 0xCABD, + 0x5F11, 0xDFB1, + 0x5F13, 0xB9AD, + 0x5F15, 0xD2FD, + 0x5F17, 0xB8A5, + 0x5F18, 0xBAEB, + 0x5F1B, 0xB3DA, + 0x5F1F, 0xB5DC, + 0x5F20, 0xD5C5, + 0x5F25, 0xC3D6, + 0x5F26, 0xCFD2, + 0x5F27, 0xBBA1, + 0x5F29, 0xE5F3, + 0x5F2A, 0xE5F2, + 0x5F2D, 0xE5F4, + 0x5F2F, 0xCDE4, + 0x5F31, 0xC8F5, + 0x5F39, 0xB5AF, + 0x5F3A, 0xC7BF, + 0x5F3C, 0xE5F6, + 0x5F40, 0xECB0, + 0x5F50, 0xE5E6, + 0x5F52, 0xB9E9, + 0x5F53, 0xB5B1, + 0x5F55, 0xC2BC, + 0x5F56, 0xE5E8, + 0x5F57, 0xE5E7, + 0x5F58, 0xE5E9, + 0x5F5D, 0xD2CD, + 0x5F61, 0xE1EA, + 0x5F62, 0xD0CE, + 0x5F64, 0xCDAE, + 0x5F66, 0xD1E5, + 0x5F69, 0xB2CA, + 0x5F6A, 0xB1EB, + 0x5F6C, 0xB1F2, + 0x5F6D, 0xC5ED, + 0x5F70, 0xD5C3, + 0x5F71, 0xD3B0, + 0x5F73, 0xE1DC, + 0x5F77, 0xE1DD, + 0x5F79, 0xD2DB, + 0x5F7B, 0xB3B9, + 0x5F7C, 0xB1CB, + 0x5F80, 0xCDF9, + 0x5F81, 0xD5F7, + 0x5F82, 0xE1DE, + 0x5F84, 0xBEB6, + 0x5F85, 0xB4FD, + 0x5F87, 0xE1DF, + 0x5F88, 0xBADC, + 0x5F89, 0xE1E0, + 0x5F8A, 0xBBB2, + 0x5F8B, 0xC2C9, + 0x5F8C, 0xE1E1, + 0x5F90, 0xD0EC, + 0x5F92, 0xCDBD, + 0x5F95, 0xE1E2, + 0x5F97, 0xB5C3, + 0x5F98, 0xC5C7, + 0x5F99, 0xE1E3, + 0x5F9C, 0xE1E4, + 0x5FA1, 0xD3F9, + 0x5FA8, 0xE1E5, + 0x5FAA, 0xD1AD, + 0x5FAD, 0xE1E6, + 0x5FAE, 0xCEA2, + 0x5FB5, 0xE1E7, + 0x5FB7, 0xB5C2, + 0x5FBC, 0xE1E8, + 0x5FBD, 0xBBD5, + 0x5FC3, 0xD0C4, + 0x5FC4, 0xE2E0, + 0x5FC5, 0xB1D8, + 0x5FC6, 0xD2E4, + 0x5FC9, 0xE2E1, + 0x5FCC, 0xBCC9, + 0x5FCD, 0xC8CC, + 0x5FCF, 0xE2E3, + 0x5FD0, 0xECFE, + 0x5FD1, 0xECFD, + 0x5FD2, 0xDFAF, + 0x5FD6, 0xE2E2, + 0x5FD7, 0xD6BE, + 0x5FD8, 0xCDFC, + 0x5FD9, 0xC3A6, + 0x5FDD, 0xE3C3, + 0x5FE0, 0xD6D2, + 0x5FE1, 0xE2E7, + 0x5FE4, 0xE2E8, + 0x5FE7, 0xD3C7, + 0x5FEA, 0xE2EC, + 0x5FEB, 0xBFEC, + 0x5FED, 0xE2ED, + 0x5FEE, 0xE2E5, + 0x5FF1, 0xB3C0, + 0x5FF5, 0xC4EE, + 0x5FF8, 0xE2EE, + 0x5FFB, 0xD0C3, + 0x5FFD, 0xBAF6, + 0x5FFE, 0xE2E9, + 0x5FFF, 0xB7DE, + 0x6000, 0xBBB3, + 0x6001, 0xCCAC, + 0x6002, 0xCBCB, + 0x6003, 0xE2E4, + 0x6004, 0xE2E6, + 0x6005, 0xE2EA, + 0x6006, 0xE2EB, + 0x600A, 0xE2F7, + 0x600D, 0xE2F4, + 0x600E, 0xD4F5, + 0x600F, 0xE2F3, + 0x6012, 0xC5AD, + 0x6014, 0xD5FA, + 0x6015, 0xC5C2, + 0x6016, 0xB2C0, + 0x6019, 0xE2EF, + 0x601B, 0xE2F2, + 0x601C, 0xC1AF, + 0x601D, 0xCBBC, + 0x6020, 0xB5A1, + 0x6021, 0xE2F9, + 0x6025, 0xBCB1, + 0x6026, 0xE2F1, + 0x6027, 0xD0D4, + 0x6028, 0xD4B9, + 0x6029, 0xE2F5, + 0x602A, 0xB9D6, + 0x602B, 0xE2F6, + 0x602F, 0xC7D3, + 0x6035, 0xE2F0, + 0x603B, 0xD7DC, + 0x603C, 0xEDA1, + 0x603F, 0xE2F8, + 0x6041, 0xEDA5, + 0x6042, 0xE2FE, + 0x6043, 0xCAD1, + 0x604B, 0xC1B5, + 0x604D, 0xBBD0, + 0x6050, 0xBFD6, + 0x6052, 0xBAE3, + 0x6055, 0xCBA1, + 0x6059, 0xEDA6, + 0x605A, 0xEDA3, + 0x605D, 0xEDA2, + 0x6062, 0xBBD6, + 0x6063, 0xEDA7, + 0x6064, 0xD0F4, + 0x6067, 0xEDA4, + 0x6068, 0xBADE, + 0x6069, 0xB6F7, + 0x606A, 0xE3A1, + 0x606B, 0xB6B2, + 0x606C, 0xCCF1, + 0x606D, 0xB9A7, + 0x606F, 0xCFA2, + 0x6070, 0xC7A1, + 0x6073, 0xBFD2, + 0x6076, 0xB6F1, + 0x6078, 0xE2FA, + 0x6079, 0xE2FB, + 0x607A, 0xE2FD, + 0x607B, 0xE2FC, + 0x607C, 0xC4D5, + 0x607D, 0xE3A2, + 0x607F, 0xD3C1, + 0x6083, 0xE3A7, + 0x6084, 0xC7C4, + 0x6089, 0xCFA4, + 0x608C, 0xE3A9, + 0x608D, 0xBAB7, + 0x6092, 0xE3A8, + 0x6094, 0xBBDA, + 0x6096, 0xE3A3, + 0x609A, 0xE3A4, + 0x609B, 0xE3AA, + 0x609D, 0xE3A6, + 0x609F, 0xCEF2, + 0x60A0, 0xD3C6, + 0x60A3, 0xBBBC, + 0x60A6, 0xD4C3, + 0x60A8, 0xC4FA, + 0x60AB, 0xEDA8, + 0x60AC, 0xD0FC, + 0x60AD, 0xE3A5, + 0x60AF, 0xC3F5, + 0x60B1, 0xE3AD, + 0x60B2, 0xB1AF, + 0x60B4, 0xE3B2, + 0x60B8, 0xBCC2, + 0x60BB, 0xE3AC, + 0x60BC, 0xB5BF, + 0x60C5, 0xC7E9, + 0x60C6, 0xE3B0, + 0x60CA, 0xBEAA, + 0x60CB, 0xCDEF, + 0x60D1, 0xBBF3, + 0x60D5, 0xCCE8, + 0x60D8, 0xE3AF, + 0x60DA, 0xE3B1, + 0x60DC, 0xCFA7, + 0x60DD, 0xE3AE, + 0x60DF, 0xCEA9, + 0x60E0, 0xBBDD, + 0x60E6, 0xB5EB, + 0x60E7, 0xBEE5, + 0x60E8, 0xB2D2, + 0x60E9, 0xB3CD, + 0x60EB, 0xB1B9, + 0x60EC, 0xE3AB, + 0x60ED, 0xB2D1, + 0x60EE, 0xB5AC, + 0x60EF, 0xB9DF, + 0x60F0, 0xB6E8, + 0x60F3, 0xCFEB, + 0x60F4, 0xE3B7, + 0x60F6, 0xBBCC, + 0x60F9, 0xC8C7, + 0x60FA, 0xD0CA, + 0x6100, 0xE3B8, + 0x6101, 0xB3EE, + 0x6106, 0xEDA9, + 0x6108, 0xD3FA, + 0x6109, 0xD3E4, + 0x610D, 0xEDAA, + 0x610E, 0xE3B9, + 0x610F, 0xD2E2, + 0x6115, 0xE3B5, + 0x611A, 0xD3DE, + 0x611F, 0xB8D0, + 0x6120, 0xE3B3, + 0x6123, 0xE3B6, + 0x6124, 0xB7DF, + 0x6126, 0xE3B4, + 0x6127, 0xC0A2, + 0x612B, 0xE3BA, + 0x613F, 0xD4B8, + 0x6148, 0xB4C8, + 0x614A, 0xE3BB, + 0x614C, 0xBBC5, + 0x614E, 0xC9F7, + 0x6151, 0xC9E5, + 0x6155, 0xC4BD, + 0x615D, 0xEDAB, + 0x6162, 0xC2FD, + 0x6167, 0xBBDB, + 0x6168, 0xBFAE, + 0x6170, 0xCEBF, + 0x6175, 0xE3BC, + 0x6177, 0xBFB6, + 0x618B, 0xB1EF, + 0x618E, 0xD4F7, + 0x6194, 0xE3BE, + 0x619D, 0xEDAD, + 0x61A7, 0xE3BF, + 0x61A8, 0xBAA9, + 0x61A9, 0xEDAC, + 0x61AC, 0xE3BD, + 0x61B7, 0xE3C0, + 0x61BE, 0xBAB6, + 0x61C2, 0xB6AE, + 0x61C8, 0xD0B8, + 0x61CA, 0xB0C3, + 0x61CB, 0xEDAE, + 0x61D1, 0xEDAF, + 0x61D2, 0xC0C1, + 0x61D4, 0xE3C1, + 0x61E6, 0xC5B3, + 0x61F5, 0xE3C2, + 0x61FF, 0xDCB2, + 0x6206, 0xEDB0, + 0x6208, 0xB8EA, + 0x620A, 0xCEEC, + 0x620B, 0xEAA7, + 0x620C, 0xD0E7, + 0x620D, 0xCAF9, + 0x620E, 0xC8D6, + 0x620F, 0xCFB7, + 0x6210, 0xB3C9, + 0x6211, 0xCED2, + 0x6212, 0xBDE4, + 0x6215, 0xE3DE, + 0x6216, 0xBBF2, + 0x6217, 0xEAA8, + 0x6218, 0xD5BD, + 0x621A, 0xC6DD, + 0x621B, 0xEAA9, + 0x621F, 0xEAAA, + 0x6221, 0xEAAC, + 0x6222, 0xEAAB, + 0x6224, 0xEAAE, + 0x6225, 0xEAAD, + 0x622A, 0xBDD8, + 0x622C, 0xEAAF, + 0x622E, 0xC2BE, + 0x6233, 0xB4C1, + 0x6234, 0xB4F7, + 0x6237, 0xBBA7, + 0x623D, 0xECE6, + 0x623E, 0xECE5, + 0x623F, 0xB7BF, + 0x6240, 0xCBF9, + 0x6241, 0xB1E2, + 0x6243, 0xECE7, + 0x6247, 0xC9C8, + 0x6248, 0xECE8, + 0x6249, 0xECE9, + 0x624B, 0xCAD6, + 0x624C, 0xDED0, + 0x624D, 0xB2C5, + 0x624E, 0xD4FA, + 0x6251, 0xC6CB, + 0x6252, 0xB0C7, + 0x6253, 0xB4F2, + 0x6254, 0xC8D3, + 0x6258, 0xCDD0, + 0x625B, 0xBFB8, + 0x6263, 0xBFDB, + 0x6266, 0xC7A4, + 0x6267, 0xD6B4, + 0x6269, 0xC0A9, + 0x626A, 0xDED1, + 0x626B, 0xC9A8, + 0x626C, 0xD1EF, + 0x626D, 0xC5A4, + 0x626E, 0xB0E7, + 0x626F, 0xB3B6, + 0x6270, 0xC8C5, + 0x6273, 0xB0E2, + 0x6276, 0xB7F6, + 0x6279, 0xC5FA, + 0x627C, 0xB6F3, + 0x627E, 0xD5D2, + 0x627F, 0xB3D0, + 0x6280, 0xBCBC, + 0x6284, 0xB3AD, + 0x6289, 0xBEF1, + 0x628A, 0xB0D1, + 0x6291, 0xD2D6, + 0x6292, 0xCAE3, + 0x6293, 0xD7A5, + 0x6295, 0xCDB6, + 0x6296, 0xB6B6, + 0x6297, 0xBFB9, + 0x6298, 0xD5DB, + 0x629A, 0xB8A7, + 0x629B, 0xC5D7, + 0x629F, 0xDED2, + 0x62A0, 0xBFD9, + 0x62A1, 0xC2D5, + 0x62A2, 0xC7C0, + 0x62A4, 0xBBA4, + 0x62A5, 0xB1A8, + 0x62A8, 0xC5EA, + 0x62AB, 0xC5FB, + 0x62AC, 0xCCA7, + 0x62B1, 0xB1A7, + 0x62B5, 0xB5D6, + 0x62B9, 0xC4A8, + 0x62BB, 0xDED3, + 0x62BC, 0xD1BA, + 0x62BD, 0xB3E9, + 0x62BF, 0xC3F2, + 0x62C2, 0xB7F7, + 0x62C4, 0xD6F4, + 0x62C5, 0xB5A3, + 0x62C6, 0xB2F0, + 0x62C7, 0xC4B4, + 0x62C8, 0xC4E9, + 0x62C9, 0xC0AD, + 0x62CA, 0xDED4, + 0x62CC, 0xB0E8, + 0x62CD, 0xC5C4, + 0x62CE, 0xC1E0, + 0x62D0, 0xB9D5, + 0x62D2, 0xBEDC, + 0x62D3, 0xCDD8, + 0x62D4, 0xB0CE, + 0x62D6, 0xCDCF, + 0x62D7, 0xDED6, + 0x62D8, 0xBED0, + 0x62D9, 0xD7BE, + 0x62DA, 0xDED5, + 0x62DB, 0xD5D0, + 0x62DC, 0xB0DD, + 0x62DF, 0xC4E2, + 0x62E2, 0xC2A3, + 0x62E3, 0xBCF0, + 0x62E5, 0xD3B5, + 0x62E6, 0xC0B9, + 0x62E7, 0xC5A1, + 0x62E8, 0xB2A6, + 0x62E9, 0xD4F1, + 0x62EC, 0xC0A8, + 0x62ED, 0xCAC3, + 0x62EE, 0xDED7, + 0x62EF, 0xD5FC, + 0x62F1, 0xB9B0, + 0x62F3, 0xC8AD, + 0x62F4, 0xCBA9, + 0x62F6, 0xDED9, + 0x62F7, 0xBFBD, + 0x62FC, 0xC6B4, + 0x62FD, 0xD7A7, + 0x62FE, 0xCAB0, + 0x62FF, 0xC4C3, + 0x6301, 0xB3D6, + 0x6302, 0xB9D2, + 0x6307, 0xD6B8, + 0x6308, 0xEAFC, + 0x6309, 0xB0B4, + 0x630E, 0xBFE6, + 0x6311, 0xCCF4, + 0x6316, 0xCDDA, + 0x631A, 0xD6BF, + 0x631B, 0xC2CE, + 0x631D, 0xCECE, + 0x631E, 0xCCA2, + 0x631F, 0xD0AE, + 0x6320, 0xC4D3, + 0x6321, 0xB5B2, + 0x6322, 0xDED8, + 0x6323, 0xD5F5, + 0x6324, 0xBCB7, + 0x6325, 0xBBD3, + 0x6328, 0xB0A4, + 0x632A, 0xC5B2, + 0x632B, 0xB4EC, + 0x632F, 0xD5F1, + 0x6332, 0xEAFD, + 0x6339, 0xDEDA, + 0x633A, 0xCDA6, + 0x633D, 0xCDEC, + 0x6342, 0xCEE6, + 0x6343, 0xDEDC, + 0x6345, 0xCDB1, + 0x6346, 0xC0A6, + 0x6349, 0xD7BD, + 0x634B, 0xDEDB, + 0x634C, 0xB0C6, + 0x634D, 0xBAB4, + 0x634E, 0xC9D3, + 0x634F, 0xC4F3, + 0x6350, 0xBEE8, + 0x6355, 0xB2B6, + 0x635E, 0xC0CC, + 0x635F, 0xCBF0, + 0x6361, 0xBCF1, + 0x6362, 0xBBBB, + 0x6363, 0xB5B7, + 0x6367, 0xC5F5, + 0x6369, 0xDEE6, + 0x636D, 0xDEE3, + 0x636E, 0xBEDD, + 0x6371, 0xDEDF, + 0x6376, 0xB4B7, + 0x6377, 0xBDDD, + 0x637A, 0xDEE0, + 0x637B, 0xC4ED, + 0x6380, 0xCFC6, + 0x6382, 0xB5E0, + 0x6387, 0xB6DE, + 0x6388, 0xCADA, + 0x6389, 0xB5F4, + 0x638A, 0xDEE5, + 0x638C, 0xD5C6, + 0x638E, 0xDEE1, + 0x638F, 0xCCCD, + 0x6390, 0xC6FE, + 0x6392, 0xC5C5, + 0x6396, 0xD2B4, + 0x6398, 0xBEF2, + 0x63A0, 0xC2D3, + 0x63A2, 0xCCBD, + 0x63A3, 0xB3B8, + 0x63A5, 0xBDD3, + 0x63A7, 0xBFD8, + 0x63A8, 0xCDC6, + 0x63A9, 0xD1DA, + 0x63AA, 0xB4EB, + 0x63AC, 0xDEE4, + 0x63AD, 0xDEDD, + 0x63AE, 0xDEE7, + 0x63B0, 0xEAFE, + 0x63B3, 0xC2B0, + 0x63B4, 0xDEE2, + 0x63B7, 0xD6C0, + 0x63B8, 0xB5A7, + 0x63BA, 0xB2F4, + 0x63BC, 0xDEE8, + 0x63BE, 0xDEF2, + 0x63C4, 0xDEED, + 0x63C6, 0xDEF1, + 0x63C9, 0xC8E0, + 0x63CD, 0xD7E1, + 0x63CE, 0xDEEF, + 0x63CF, 0xC3E8, + 0x63D0, 0xCCE1, + 0x63D2, 0xB2E5, + 0x63D6, 0xD2BE, + 0x63DE, 0xDEEE, + 0x63E0, 0xDEEB, + 0x63E1, 0xCED5, + 0x63E3, 0xB4A7, + 0x63E9, 0xBFAB, + 0x63EA, 0xBEBE, + 0x63ED, 0xBDD2, + 0x63F2, 0xDEE9, + 0x63F4, 0xD4AE, + 0x63F6, 0xDEDE, + 0x63F8, 0xDEEA, + 0x63FD, 0xC0BF, + 0x63FF, 0xDEEC, + 0x6400, 0xB2F3, + 0x6401, 0xB8E9, + 0x6402, 0xC2A7, + 0x6405, 0xBDC1, + 0x640B, 0xDEF5, + 0x640C, 0xDEF8, + 0x640F, 0xB2AB, + 0x6410, 0xB4A4, + 0x6413, 0xB4EA, + 0x6414, 0xC9A6, + 0x641B, 0xDEF6, + 0x641C, 0xCBD1, + 0x641E, 0xB8E3, + 0x6420, 0xDEF7, + 0x6421, 0xDEFA, + 0x6426, 0xDEF9, + 0x642A, 0xCCC2, + 0x642C, 0xB0E1, + 0x642D, 0xB4EE, + 0x6434, 0xE5BA, + 0x643A, 0xD0AF, + 0x643D, 0xB2EB, + 0x643F, 0xEBA1, + 0x6441, 0xDEF4, + 0x6444, 0xC9E3, + 0x6445, 0xDEF3, + 0x6446, 0xB0DA, + 0x6447, 0xD2A1, + 0x6448, 0xB1F7, + 0x644A, 0xCCAF, + 0x6452, 0xDEF0, + 0x6454, 0xCBA4, + 0x6458, 0xD5AA, + 0x645E, 0xDEFB, + 0x6467, 0xB4DD, + 0x6469, 0xC4A6, + 0x646D, 0xDEFD, + 0x6478, 0xC3FE, + 0x6479, 0xC4A1, + 0x647A, 0xDFA1, + 0x6482, 0xC1CC, + 0x6484, 0xDEFC, + 0x6485, 0xBEEF, + 0x6487, 0xC6B2, + 0x6491, 0xB3C5, + 0x6492, 0xC8F6, + 0x6495, 0xCBBA, + 0x6496, 0xDEFE, + 0x6499, 0xDFA4, + 0x649E, 0xD7B2, + 0x64A4, 0xB3B7, + 0x64A9, 0xC1C3, + 0x64AC, 0xC7CB, + 0x64AD, 0xB2A5, + 0x64AE, 0xB4E9, + 0x64B0, 0xD7AB, + 0x64B5, 0xC4EC, + 0x64B7, 0xDFA2, + 0x64B8, 0xDFA3, + 0x64BA, 0xDFA5, + 0x64BC, 0xBAB3, + 0x64C0, 0xDFA6, + 0x64C2, 0xC0DE, + 0x64C5, 0xC9C3, + 0x64CD, 0xB2D9, + 0x64CE, 0xC7E6, + 0x64D0, 0xDFA7, + 0x64D2, 0xC7DC, + 0x64D7, 0xDFA8, + 0x64D8, 0xEBA2, + 0x64DE, 0xCBD3, + 0x64E2, 0xDFAA, + 0x64E4, 0xDFA9, + 0x64E6, 0xB2C1, + 0x6500, 0xC5CA, + 0x6509, 0xDFAB, + 0x6512, 0xD4DC, + 0x6518, 0xC8C1, + 0x6525, 0xDFAC, + 0x652B, 0xBEF0, + 0x652E, 0xDFAD, + 0x652F, 0xD6A7, + 0x6534, 0xEAB7, + 0x6535, 0xEBB6, + 0x6536, 0xCAD5, + 0x6538, 0xD8FC, + 0x6539, 0xB8C4, + 0x653B, 0xB9A5, + 0x653E, 0xB7C5, + 0x653F, 0xD5FE, + 0x6545, 0xB9CA, + 0x6548, 0xD0A7, + 0x6549, 0xF4CD, + 0x654C, 0xB5D0, + 0x654F, 0xC3F4, + 0x6551, 0xBEC8, + 0x6555, 0xEBB7, + 0x6556, 0xB0BD, + 0x6559, 0xBDCC, + 0x655B, 0xC1B2, + 0x655D, 0xB1D6, + 0x655E, 0xB3A8, + 0x6562, 0xB8D2, + 0x6563, 0xC9A2, + 0x6566, 0xB6D8, + 0x656B, 0xEBB8, + 0x656C, 0xBEB4, + 0x6570, 0xCAFD, + 0x6572, 0xC7C3, + 0x6574, 0xD5FB, + 0x6577, 0xB7F3, + 0x6587, 0xCEC4, + 0x658B, 0xD5AB, + 0x658C, 0xB1F3, + 0x6590, 0xECB3, + 0x6591, 0xB0DF, + 0x6593, 0xECB5, + 0x6597, 0xB6B7, + 0x6599, 0xC1CF, + 0x659B, 0xF5FA, + 0x659C, 0xD0B1, + 0x659F, 0xD5E5, + 0x65A1, 0xCED3, + 0x65A4, 0xBDEF, + 0x65A5, 0xB3E2, + 0x65A7, 0xB8AB, + 0x65A9, 0xD5B6, + 0x65AB, 0xEDBD, + 0x65AD, 0xB6CF, + 0x65AF, 0xCBB9, + 0x65B0, 0xD0C2, + 0x65B9, 0xB7BD, + 0x65BC, 0xECB6, + 0x65BD, 0xCAA9, + 0x65C1, 0xC5D4, + 0x65C3, 0xECB9, + 0x65C4, 0xECB8, + 0x65C5, 0xC2C3, + 0x65C6, 0xECB7, + 0x65CB, 0xD0FD, + 0x65CC, 0xECBA, + 0x65CE, 0xECBB, + 0x65CF, 0xD7E5, + 0x65D2, 0xECBC, + 0x65D6, 0xECBD, + 0x65D7, 0xC6EC, + 0x65E0, 0xCEDE, + 0x65E2, 0xBCC8, + 0x65E5, 0xC8D5, + 0x65E6, 0xB5A9, + 0x65E7, 0xBEC9, + 0x65E8, 0xD6BC, + 0x65E9, 0xD4E7, + 0x65EC, 0xD1AE, + 0x65ED, 0xD0F1, + 0x65EE, 0xEAB8, + 0x65EF, 0xEAB9, + 0x65F0, 0xEABA, + 0x65F1, 0xBAB5, + 0x65F6, 0xCAB1, + 0x65F7, 0xBFF5, + 0x65FA, 0xCDFA, + 0x6600, 0xEAC0, + 0x6602, 0xB0BA, + 0x6603, 0xEABE, + 0x6606, 0xC0A5, + 0x660A, 0xEABB, + 0x660C, 0xB2FD, + 0x660E, 0xC3F7, + 0x660F, 0xBBE8, + 0x6613, 0xD2D7, + 0x6614, 0xCEF4, + 0x6615, 0xEABF, + 0x6619, 0xEABC, + 0x661D, 0xEAC3, + 0x661F, 0xD0C7, + 0x6620, 0xD3B3, + 0x6625, 0xB4BA, + 0x6627, 0xC3C1, + 0x6628, 0xD7F2, + 0x662D, 0xD5D1, + 0x662F, 0xCAC7, + 0x6631, 0xEAC5, + 0x6634, 0xEAC4, + 0x6635, 0xEAC7, + 0x6636, 0xEAC6, + 0x663C, 0xD6E7, + 0x663E, 0xCFD4, + 0x6641, 0xEACB, + 0x6643, 0xBBCE, + 0x664B, 0xBDFA, + 0x664C, 0xC9CE, + 0x664F, 0xEACC, + 0x6652, 0xC9B9, + 0x6653, 0xCFFE, + 0x6654, 0xEACA, + 0x6655, 0xD4CE, + 0x6656, 0xEACD, + 0x6657, 0xEACF, + 0x665A, 0xCDED, + 0x665F, 0xEAC9, + 0x6661, 0xEACE, + 0x6664, 0xCEEE, + 0x6666, 0xBBDE, + 0x6668, 0xB3BF, + 0x666E, 0xC6D5, + 0x666F, 0xBEB0, + 0x6670, 0xCEFA, + 0x6674, 0xC7E7, + 0x6676, 0xBEA7, + 0x6677, 0xEAD0, + 0x667A, 0xD6C7, + 0x667E, 0xC1C0, + 0x6682, 0xD4DD, + 0x6684, 0xEAD1, + 0x6687, 0xCFBE, + 0x668C, 0xEAD2, + 0x6691, 0xCAEE, + 0x6696, 0xC5AF, + 0x6697, 0xB0B5, + 0x669D, 0xEAD4, + 0x66A7, 0xEAD3, + 0x66A8, 0xF4DF, + 0x66AE, 0xC4BA, + 0x66B4, 0xB1A9, + 0x66B9, 0xE5DF, + 0x66BE, 0xEAD5, + 0x66D9, 0xCAEF, + 0x66DB, 0xEAD6, + 0x66DC, 0xEAD7, + 0x66DD, 0xC6D8, + 0x66E6, 0xEAD8, + 0x66E9, 0xEAD9, + 0x66F0, 0xD4BB, + 0x66F2, 0xC7FA, + 0x66F3, 0xD2B7, + 0x66F4, 0xB8FC, + 0x66F7, 0xEAC2, + 0x66F9, 0xB2DC, + 0x66FC, 0xC2FC, + 0x66FE, 0xD4F8, + 0x66FF, 0xCCE6, + 0x6700, 0xD7EE, + 0x6708, 0xD4C2, + 0x6709, 0xD3D0, + 0x670A, 0xEBC3, + 0x670B, 0xC5F3, + 0x670D, 0xB7FE, + 0x6710, 0xEBD4, + 0x6714, 0xCBB7, + 0x6715, 0xEBDE, + 0x6717, 0xC0CA, + 0x671B, 0xCDFB, + 0x671D, 0xB3AF, + 0x671F, 0xC6DA, + 0x6726, 0xEBFC, + 0x6728, 0xC4BE, + 0x672A, 0xCEB4, + 0x672B, 0xC4A9, + 0x672C, 0xB1BE, + 0x672D, 0xD4FD, + 0x672F, 0xCAF5, + 0x6731, 0xD6EC, + 0x6734, 0xC6D3, + 0x6735, 0xB6E4, + 0x673A, 0xBBFA, + 0x673D, 0xD0E0, + 0x6740, 0xC9B1, + 0x6742, 0xD4D3, + 0x6743, 0xC8A8, + 0x6746, 0xB8CB, + 0x6748, 0xE8BE, + 0x6749, 0xC9BC, + 0x674C, 0xE8BB, + 0x674E, 0xC0EE, + 0x674F, 0xD0D3, + 0x6750, 0xB2C4, + 0x6751, 0xB4E5, + 0x6753, 0xE8BC, + 0x6756, 0xD5C8, + 0x675C, 0xB6C5, + 0x675E, 0xE8BD, + 0x675F, 0xCAF8, + 0x6760, 0xB8DC, + 0x6761, 0xCCF5, + 0x6765, 0xC0B4, + 0x6768, 0xD1EE, + 0x6769, 0xE8BF, + 0x676A, 0xE8C2, + 0x676D, 0xBABC, + 0x676F, 0xB1AD, + 0x6770, 0xBDDC, + 0x6772, 0xEABD, + 0x6773, 0xE8C3, + 0x6775, 0xE8C6, + 0x6777, 0xE8CB, + 0x677C, 0xE8CC, + 0x677E, 0xCBC9, + 0x677F, 0xB0E5, + 0x6781, 0xBCAB, + 0x6784, 0xB9B9, + 0x6787, 0xE8C1, + 0x6789, 0xCDF7, + 0x678B, 0xE8CA, + 0x6790, 0xCEF6, + 0x6795, 0xD5ED, + 0x6797, 0xC1D6, + 0x6798, 0xE8C4, + 0x679A, 0xC3B6, + 0x679C, 0xB9FB, + 0x679D, 0xD6A6, + 0x679E, 0xE8C8, + 0x67A2, 0xCAE0, + 0x67A3, 0xD4E6, + 0x67A5, 0xE8C0, + 0x67A7, 0xE8C5, + 0x67A8, 0xE8C7, + 0x67AA, 0xC7B9, + 0x67AB, 0xB7E3, + 0x67AD, 0xE8C9, + 0x67AF, 0xBFDD, + 0x67B0, 0xE8D2, + 0x67B3, 0xE8D7, + 0x67B5, 0xE8D5, + 0x67B6, 0xBCDC, + 0x67B7, 0xBCCF, + 0x67B8, 0xE8DB, + 0x67C1, 0xE8DE, + 0x67C3, 0xE8DA, + 0x67C4, 0xB1FA, + 0x67CF, 0xB0D8, + 0x67D0, 0xC4B3, + 0x67D1, 0xB8CC, + 0x67D2, 0xC6E2, + 0x67D3, 0xC8BE, + 0x67D4, 0xC8E1, + 0x67D8, 0xE8CF, + 0x67D9, 0xE8D4, + 0x67DA, 0xE8D6, + 0x67DC, 0xB9F1, + 0x67DD, 0xE8D8, + 0x67DE, 0xD7F5, + 0x67E0, 0xC4FB, + 0x67E2, 0xE8DC, + 0x67E5, 0xB2E9, + 0x67E9, 0xE8D1, + 0x67EC, 0xBCED, + 0x67EF, 0xBFC2, + 0x67F0, 0xE8CD, + 0x67F1, 0xD6F9, + 0x67F3, 0xC1F8, + 0x67F4, 0xB2F1, + 0x67FD, 0xE8DF, + 0x67FF, 0xCAC1, + 0x6800, 0xE8D9, + 0x6805, 0xD5A4, + 0x6807, 0xB1EA, + 0x6808, 0xD5BB, + 0x6809, 0xE8CE, + 0x680A, 0xE8D0, + 0x680B, 0xB6B0, + 0x680C, 0xE8D3, + 0x680E, 0xE8DD, + 0x680F, 0xC0B8, + 0x6811, 0xCAF7, + 0x6813, 0xCBA8, + 0x6816, 0xC6DC, + 0x6817, 0xC0F5, + 0x681D, 0xE8E9, + 0x6821, 0xD0A3, + 0x6829, 0xE8F2, + 0x682A, 0xD6EA, + 0x6832, 0xE8E0, + 0x6833, 0xE8E1, + 0x6837, 0xD1F9, + 0x6838, 0xBACB, + 0x6839, 0xB8F9, + 0x683C, 0xB8F1, + 0x683D, 0xD4D4, + 0x683E, 0xE8EF, + 0x6840, 0xE8EE, + 0x6841, 0xE8EC, + 0x6842, 0xB9F0, + 0x6843, 0xCCD2, + 0x6844, 0xE8E6, + 0x6845, 0xCEA6, + 0x6846, 0xBFF2, + 0x6848, 0xB0B8, + 0x6849, 0xE8F1, + 0x684A, 0xE8F0, + 0x684C, 0xD7C0, + 0x684E, 0xE8E4, + 0x6850, 0xCDA9, + 0x6851, 0xC9A3, + 0x6853, 0xBBB8, + 0x6854, 0xBDDB, + 0x6855, 0xE8EA, + 0x6860, 0xE8E2, + 0x6861, 0xE8E3, + 0x6862, 0xE8E5, + 0x6863, 0xB5B5, + 0x6864, 0xE8E7, + 0x6865, 0xC7C5, + 0x6866, 0xE8EB, + 0x6867, 0xE8ED, + 0x6868, 0xBDB0, + 0x6869, 0xD7AE, + 0x686B, 0xE8F8, + 0x6874, 0xE8F5, + 0x6876, 0xCDB0, + 0x6877, 0xE8F6, + 0x6881, 0xC1BA, + 0x6883, 0xE8E8, + 0x6885, 0xC3B7, + 0x6886, 0xB0F0, + 0x688F, 0xE8F4, + 0x6893, 0xE8F7, + 0x6897, 0xB9A3, + 0x68A2, 0xC9D2, + 0x68A6, 0xC3CE, + 0x68A7, 0xCEE0, + 0x68A8, 0xC0E6, + 0x68AD, 0xCBF3, + 0x68AF, 0xCCDD, + 0x68B0, 0xD0B5, + 0x68B3, 0xCAE1, + 0x68B5, 0xE8F3, + 0x68C0, 0xBCEC, + 0x68C2, 0xE8F9, + 0x68C9, 0xC3DE, + 0x68CB, 0xC6E5, + 0x68CD, 0xB9F7, + 0x68D2, 0xB0F4, + 0x68D5, 0xD7D8, + 0x68D8, 0xBCAC, + 0x68DA, 0xC5EF, + 0x68E0, 0xCCC4, + 0x68E3, 0xE9A6, + 0x68EE, 0xC9AD, + 0x68F0, 0xE9A2, + 0x68F1, 0xC0E2, + 0x68F5, 0xBFC3, + 0x68F9, 0xE8FE, + 0x68FA, 0xB9D7, + 0x68FC, 0xE8FB, + 0x6901, 0xE9A4, + 0x6905, 0xD2CE, + 0x690B, 0xE9A3, + 0x690D, 0xD6B2, + 0x690E, 0xD7B5, + 0x6910, 0xE9A7, + 0x6912, 0xBDB7, + 0x691F, 0xE8FC, + 0x6920, 0xE8FD, + 0x6924, 0xE9A1, + 0x692D, 0xCDD6, + 0x6930, 0xD2AC, + 0x6934, 0xE9B2, + 0x6939, 0xE9A9, + 0x693D, 0xB4AA, + 0x693F, 0xB4BB, + 0x6942, 0xE9AB, + 0x6954, 0xD0A8, + 0x6957, 0xE9A5, + 0x695A, 0xB3FE, + 0x695D, 0xE9AC, + 0x695E, 0xC0E3, + 0x6960, 0xE9AA, + 0x6963, 0xE9B9, + 0x6966, 0xE9B8, + 0x696B, 0xE9AE, + 0x696E, 0xE8FA, + 0x6971, 0xE9A8, + 0x6977, 0xBFAC, + 0x6978, 0xE9B1, + 0x6979, 0xE9BA, + 0x697C, 0xC2A5, + 0x6980, 0xE9AF, + 0x6982, 0xB8C5, + 0x6984, 0xE9AD, + 0x6986, 0xD3DC, + 0x6987, 0xE9B4, + 0x6988, 0xE9B5, + 0x6989, 0xE9B7, + 0x698D, 0xE9C7, + 0x6994, 0xC0C6, + 0x6995, 0xE9C5, + 0x6998, 0xE9B0, + 0x699B, 0xE9BB, + 0x699C, 0xB0F1, + 0x69A7, 0xE9BC, + 0x69A8, 0xD5A5, + 0x69AB, 0xE9BE, + 0x69AD, 0xE9BF, + 0x69B1, 0xE9C1, + 0x69B4, 0xC1F1, + 0x69B7, 0xC8B6, + 0x69BB, 0xE9BD, + 0x69C1, 0xE9C2, + 0x69CA, 0xE9C3, + 0x69CC, 0xE9B3, + 0x69CE, 0xE9B6, + 0x69D0, 0xBBB1, + 0x69D4, 0xE9C0, + 0x69DB, 0xBCF7, + 0x69DF, 0xE9C4, + 0x69E0, 0xE9C6, + 0x69ED, 0xE9CA, + 0x69F2, 0xE9CE, + 0x69FD, 0xB2DB, + 0x69FF, 0xE9C8, + 0x6A0A, 0xB7AE, + 0x6A17, 0xE9CB, + 0x6A18, 0xE9CC, + 0x6A1F, 0xD5C1, + 0x6A21, 0xC4A3, + 0x6A28, 0xE9D8, + 0x6A2A, 0xBAE1, + 0x6A2F, 0xE9C9, + 0x6A31, 0xD3A3, + 0x6A35, 0xE9D4, + 0x6A3D, 0xE9D7, + 0x6A3E, 0xE9D0, + 0x6A44, 0xE9CF, + 0x6A47, 0xC7C1, + 0x6A50, 0xE9D2, + 0x6A58, 0xE9D9, + 0x6A59, 0xB3C8, + 0x6A5B, 0xE9D3, + 0x6A61, 0xCFF0, + 0x6A65, 0xE9CD, + 0x6A71, 0xB3F7, + 0x6A79, 0xE9D6, + 0x6A7C, 0xE9DA, + 0x6A80, 0xCCB4, + 0x6A84, 0xCFAD, + 0x6A8E, 0xE9D5, + 0x6A90, 0xE9DC, + 0x6A91, 0xE9DB, + 0x6A97, 0xE9DE, + 0x6AA0, 0xE9D1, + 0x6AA9, 0xE9DD, + 0x6AAB, 0xE9DF, + 0x6AAC, 0xC3CA, + 0x6B20, 0xC7B7, + 0x6B21, 0xB4CE, + 0x6B22, 0xBBB6, + 0x6B23, 0xD0C0, + 0x6B24, 0xECA3, + 0x6B27, 0xC5B7, + 0x6B32, 0xD3FB, + 0x6B37, 0xECA4, + 0x6B39, 0xECA5, + 0x6B3A, 0xC6DB, + 0x6B3E, 0xBFEE, + 0x6B43, 0xECA6, + 0x6B46, 0xECA7, + 0x6B47, 0xD0AA, + 0x6B49, 0xC7B8, + 0x6B4C, 0xB8E8, + 0x6B59, 0xECA8, + 0x6B62, 0xD6B9, + 0x6B63, 0xD5FD, + 0x6B64, 0xB4CB, + 0x6B65, 0xB2BD, + 0x6B66, 0xCEE4, + 0x6B67, 0xC6E7, + 0x6B6A, 0xCDE1, + 0x6B79, 0xB4F5, + 0x6B7B, 0xCBC0, + 0x6B7C, 0xBCDF, + 0x6B81, 0xE9E2, + 0x6B82, 0xE9E3, + 0x6B83, 0xD1EA, + 0x6B84, 0xE9E5, + 0x6B86, 0xB4F9, + 0x6B87, 0xE9E4, + 0x6B89, 0xD1B3, + 0x6B8A, 0xCAE2, + 0x6B8B, 0xB2D0, + 0x6B8D, 0xE9E8, + 0x6B92, 0xE9E6, + 0x6B93, 0xE9E7, + 0x6B96, 0xD6B3, + 0x6B9A, 0xE9E9, + 0x6B9B, 0xE9EA, + 0x6BA1, 0xE9EB, + 0x6BAA, 0xE9EC, + 0x6BB3, 0xECAF, + 0x6BB4, 0xC5B9, + 0x6BB5, 0xB6CE, + 0x6BB7, 0xD2F3, + 0x6BBF, 0xB5EE, + 0x6BC1, 0xBBD9, + 0x6BC2, 0xECB1, + 0x6BC5, 0xD2E3, + 0x6BCB, 0xCEE3, + 0x6BCD, 0xC4B8, + 0x6BCF, 0xC3BF, + 0x6BD2, 0xB6BE, + 0x6BD3, 0xD8B9, + 0x6BD4, 0xB1C8, + 0x6BD5, 0xB1CF, + 0x6BD6, 0xB1D1, + 0x6BD7, 0xC5FE, + 0x6BD9, 0xB1D0, + 0x6BDB, 0xC3AB, + 0x6BE1, 0xD5B1, + 0x6BEA, 0xEBA4, + 0x6BEB, 0xBAC1, + 0x6BEF, 0xCCBA, + 0x6BF3, 0xEBA5, + 0x6BF5, 0xEBA7, + 0x6BF9, 0xEBA8, + 0x6BFD, 0xEBA6, + 0x6C05, 0xEBA9, + 0x6C06, 0xEBAB, + 0x6C07, 0xEBAA, + 0x6C0D, 0xEBAC, + 0x6C0F, 0xCACF, + 0x6C10, 0xD8B5, + 0x6C11, 0xC3F1, + 0x6C13, 0xC3A5, + 0x6C14, 0xC6F8, + 0x6C15, 0xEBAD, + 0x6C16, 0xC4CA, + 0x6C18, 0xEBAE, + 0x6C19, 0xEBAF, + 0x6C1A, 0xEBB0, + 0x6C1B, 0xB7D5, + 0x6C1F, 0xB7FA, + 0x6C21, 0xEBB1, + 0x6C22, 0xC7E2, + 0x6C24, 0xEBB3, + 0x6C26, 0xBAA4, + 0x6C27, 0xD1F5, + 0x6C28, 0xB0B1, + 0x6C29, 0xEBB2, + 0x6C2A, 0xEBB4, + 0x6C2E, 0xB5AA, + 0x6C2F, 0xC2C8, + 0x6C30, 0xC7E8, + 0x6C32, 0xEBB5, + 0x6C34, 0xCBAE, + 0x6C35, 0xE3DF, + 0x6C38, 0xD3C0, + 0x6C3D, 0xD9DB, + 0x6C40, 0xCDA1, + 0x6C41, 0xD6AD, + 0x6C42, 0xC7F3, + 0x6C46, 0xD9E0, + 0x6C47, 0xBBE3, + 0x6C49, 0xBABA, + 0x6C4A, 0xE3E2, + 0x6C50, 0xCFAB, + 0x6C54, 0xE3E0, + 0x6C55, 0xC9C7, + 0x6C57, 0xBAB9, + 0x6C5B, 0xD1B4, + 0x6C5C, 0xE3E1, + 0x6C5D, 0xC8EA, + 0x6C5E, 0xB9AF, + 0x6C5F, 0xBDAD, + 0x6C60, 0xB3D8, + 0x6C61, 0xCEDB, + 0x6C64, 0xCCC0, + 0x6C68, 0xE3E8, + 0x6C69, 0xE3E9, + 0x6C6A, 0xCDF4, + 0x6C70, 0xCCAD, + 0x6C72, 0xBCB3, + 0x6C74, 0xE3EA, + 0x6C76, 0xE3EB, + 0x6C79, 0xD0DA, + 0x6C7D, 0xC6FB, + 0x6C7E, 0xB7DA, + 0x6C81, 0xC7DF, + 0x6C82, 0xD2CA, + 0x6C83, 0xCED6, + 0x6C85, 0xE3E4, + 0x6C86, 0xE3EC, + 0x6C88, 0xC9F2, + 0x6C89, 0xB3C1, + 0x6C8C, 0xE3E7, + 0x6C8F, 0xC6E3, + 0x6C90, 0xE3E5, + 0x6C93, 0xEDB3, + 0x6C94, 0xE3E6, + 0x6C99, 0xC9B3, + 0x6C9B, 0xC5E6, + 0x6C9F, 0xB9B5, + 0x6CA1, 0xC3BB, + 0x6CA3, 0xE3E3, + 0x6CA4, 0xC5BD, + 0x6CA5, 0xC1A4, + 0x6CA6, 0xC2D9, + 0x6CA7, 0xB2D7, + 0x6CA9, 0xE3ED, + 0x6CAA, 0xBBA6, + 0x6CAB, 0xC4AD, + 0x6CAD, 0xE3F0, + 0x6CAE, 0xBEDA, + 0x6CB1, 0xE3FB, + 0x6CB2, 0xE3F5, + 0x6CB3, 0xBAD3, + 0x6CB8, 0xB7D0, + 0x6CB9, 0xD3CD, + 0x6CBB, 0xD6CE, + 0x6CBC, 0xD5D3, + 0x6CBD, 0xB9C1, + 0x6CBE, 0xD5B4, + 0x6CBF, 0xD1D8, + 0x6CC4, 0xD0B9, + 0x6CC5, 0xC7F6, + 0x6CC9, 0xC8AA, + 0x6CCA, 0xB2B4, + 0x6CCC, 0xC3DA, + 0x6CD0, 0xE3EE, + 0x6CD3, 0xE3FC, + 0x6CD4, 0xE3EF, + 0x6CD5, 0xB7A8, + 0x6CD6, 0xE3F7, + 0x6CD7, 0xE3F4, + 0x6CDB, 0xB7BA, + 0x6CDE, 0xC5A2, + 0x6CE0, 0xE3F6, + 0x6CE1, 0xC5DD, + 0x6CE2, 0xB2A8, + 0x6CE3, 0xC6FC, + 0x6CE5, 0xC4E0, + 0x6CE8, 0xD7A2, + 0x6CEA, 0xC0E1, + 0x6CEB, 0xE3F9, + 0x6CEE, 0xE3FA, + 0x6CEF, 0xE3FD, + 0x6CF0, 0xCCA9, + 0x6CF1, 0xE3F3, + 0x6CF3, 0xD3BE, + 0x6CF5, 0xB1C3, + 0x6CF6, 0xEDB4, + 0x6CF7, 0xE3F1, + 0x6CF8, 0xE3F2, + 0x6CFA, 0xE3F8, + 0x6CFB, 0xD0BA, + 0x6CFC, 0xC6C3, + 0x6CFD, 0xD4F3, + 0x6CFE, 0xE3FE, + 0x6D01, 0xBDE0, + 0x6D04, 0xE4A7, + 0x6D07, 0xE4A6, + 0x6D0B, 0xD1F3, + 0x6D0C, 0xE4A3, + 0x6D0E, 0xE4A9, + 0x6D12, 0xC8F7, + 0x6D17, 0xCFB4, + 0x6D19, 0xE4A8, + 0x6D1A, 0xE4AE, + 0x6D1B, 0xC2E5, + 0x6D1E, 0xB6B4, + 0x6D25, 0xBDF2, + 0x6D27, 0xE4A2, + 0x6D2A, 0xBAE9, + 0x6D2B, 0xE4AA, + 0x6D2E, 0xE4AC, + 0x6D31, 0xB6FD, + 0x6D32, 0xD6DE, + 0x6D33, 0xE4B2, + 0x6D35, 0xE4AD, + 0x6D39, 0xE4A1, + 0x6D3B, 0xBBEE, + 0x6D3C, 0xCDDD, + 0x6D3D, 0xC7A2, + 0x6D3E, 0xC5C9, + 0x6D41, 0xC1F7, + 0x6D43, 0xE4A4, + 0x6D45, 0xC7B3, + 0x6D46, 0xBDAC, + 0x6D47, 0xBDBD, + 0x6D48, 0xE4A5, + 0x6D4A, 0xD7C7, + 0x6D4B, 0xB2E2, + 0x6D4D, 0xE4AB, + 0x6D4E, 0xBCC3, + 0x6D4F, 0xE4AF, + 0x6D51, 0xBBEB, + 0x6D52, 0xE4B0, + 0x6D53, 0xC5A8, + 0x6D54, 0xE4B1, + 0x6D59, 0xD5E3, + 0x6D5A, 0xBFA3, + 0x6D5C, 0xE4BA, + 0x6D5E, 0xE4B7, + 0x6D60, 0xE4BB, + 0x6D63, 0xE4BD, + 0x6D66, 0xC6D6, + 0x6D69, 0xBAC6, + 0x6D6A, 0xC0CB, + 0x6D6E, 0xB8A1, + 0x6D6F, 0xE4B4, + 0x6D74, 0xD4A1, + 0x6D77, 0xBAA3, + 0x6D78, 0xBDFE, + 0x6D7C, 0xE4BC, + 0x6D82, 0xCDBF, + 0x6D85, 0xC4F9, + 0x6D88, 0xCFFB, + 0x6D89, 0xC9E6, + 0x6D8C, 0xD3BF, + 0x6D8E, 0xCFD1, + 0x6D91, 0xE4B3, + 0x6D93, 0xE4B8, + 0x6D94, 0xE4B9, + 0x6D95, 0xCCE9, + 0x6D9B, 0xCCCE, + 0x6D9D, 0xC0D4, + 0x6D9E, 0xE4B5, + 0x6D9F, 0xC1B0, + 0x6DA0, 0xE4B6, + 0x6DA1, 0xCED0, + 0x6DA3, 0xBBC1, + 0x6DA4, 0xB5D3, + 0x6DA6, 0xC8F3, + 0x6DA7, 0xBDA7, + 0x6DA8, 0xD5C7, + 0x6DA9, 0xC9AC, + 0x6DAA, 0xB8A2, + 0x6DAB, 0xE4CA, + 0x6DAE, 0xE4CC, + 0x6DAF, 0xD1C4, + 0x6DB2, 0xD2BA, + 0x6DB5, 0xBAAD, + 0x6DB8, 0xBAD4, + 0x6DBF, 0xE4C3, + 0x6DC0, 0xB5ED, + 0x6DC4, 0xD7CD, + 0x6DC5, 0xE4C0, + 0x6DC6, 0xCFFD, + 0x6DC7, 0xE4BF, + 0x6DCB, 0xC1DC, + 0x6DCC, 0xCCCA, + 0x6DD1, 0xCAE7, + 0x6DD6, 0xC4D7, + 0x6DD8, 0xCCD4, + 0x6DD9, 0xE4C8, + 0x6DDD, 0xE4C7, + 0x6DDE, 0xE4C1, + 0x6DE0, 0xE4C4, + 0x6DE1, 0xB5AD, + 0x6DE4, 0xD3D9, + 0x6DE6, 0xE4C6, + 0x6DEB, 0xD2F9, + 0x6DEC, 0xB4E3, + 0x6DEE, 0xBBB4, + 0x6DF1, 0xC9EE, + 0x6DF3, 0xB4BE, + 0x6DF7, 0xBBEC, + 0x6DF9, 0xD1CD, + 0x6DFB, 0xCCED, + 0x6DFC, 0xEDB5, + 0x6E05, 0xC7E5, + 0x6E0A, 0xD4A8, + 0x6E0C, 0xE4CB, + 0x6E0D, 0xD7D5, + 0x6E0E, 0xE4C2, + 0x6E10, 0xBDA5, + 0x6E11, 0xE4C5, + 0x6E14, 0xD3E6, + 0x6E16, 0xE4C9, + 0x6E17, 0xC9F8, + 0x6E1A, 0xE4BE, + 0x6E1D, 0xD3E5, + 0x6E20, 0xC7FE, + 0x6E21, 0xB6C9, + 0x6E23, 0xD4FC, + 0x6E24, 0xB2B3, + 0x6E25, 0xE4D7, + 0x6E29, 0xCEC2, + 0x6E2B, 0xE4CD, + 0x6E2D, 0xCEBC, + 0x6E2F, 0xB8DB, + 0x6E32, 0xE4D6, + 0x6E34, 0xBFCA, + 0x6E38, 0xD3CE, + 0x6E3A, 0xC3EC, + 0x6E43, 0xC5C8, + 0x6E44, 0xE4D8, + 0x6E4D, 0xCDC4, + 0x6E4E, 0xE4CF, + 0x6E53, 0xE4D4, + 0x6E54, 0xE4D5, + 0x6E56, 0xBAFE, + 0x6E58, 0xCFE6, + 0x6E5B, 0xD5BF, + 0x6E5F, 0xE4D2, + 0x6E6B, 0xE4D0, + 0x6E6E, 0xE4CE, + 0x6E7E, 0xCDE5, + 0x6E7F, 0xCAAA, + 0x6E83, 0xC0A3, + 0x6E85, 0xBDA6, + 0x6E86, 0xE4D3, + 0x6E89, 0xB8C8, + 0x6E8F, 0xE4E7, + 0x6E90, 0xD4B4, + 0x6E98, 0xE4DB, + 0x6E9C, 0xC1EF, + 0x6E9F, 0xE4E9, + 0x6EA2, 0xD2E7, + 0x6EA5, 0xE4DF, + 0x6EA7, 0xE4E0, + 0x6EAA, 0xCFAA, + 0x6EAF, 0xCBDD, + 0x6EB1, 0xE4DA, + 0x6EB2, 0xE4D1, + 0x6EB4, 0xE4E5, + 0x6EB6, 0xC8DC, + 0x6EB7, 0xE4E3, + 0x6EBA, 0xC4E7, + 0x6EBB, 0xE4E2, + 0x6EBD, 0xE4E1, + 0x6EC1, 0xB3FC, + 0x6EC2, 0xE4E8, + 0x6EC7, 0xB5E1, + 0x6ECB, 0xD7CC, + 0x6ECF, 0xE4E6, + 0x6ED1, 0xBBAC, + 0x6ED3, 0xD7D2, + 0x6ED4, 0xCCCF, + 0x6ED5, 0xEBF8, + 0x6ED7, 0xE4E4, + 0x6EDA, 0xB9F6, + 0x6EDE, 0xD6CD, + 0x6EDF, 0xE4D9, + 0x6EE0, 0xE4DC, + 0x6EE1, 0xC2FA, + 0x6EE2, 0xE4DE, + 0x6EE4, 0xC2CB, + 0x6EE5, 0xC0C4, + 0x6EE6, 0xC2D0, + 0x6EE8, 0xB1F5, + 0x6EE9, 0xCCB2, + 0x6EF4, 0xB5CE, + 0x6EF9, 0xE4EF, + 0x6F02, 0xC6AF, + 0x6F06, 0xC6E1, + 0x6F09, 0xE4F5, + 0x6F0F, 0xC2A9, + 0x6F13, 0xC0EC, + 0x6F14, 0xD1DD, + 0x6F15, 0xE4EE, + 0x6F20, 0xC4AE, + 0x6F24, 0xE4ED, + 0x6F29, 0xE4F6, + 0x6F2A, 0xE4F4, + 0x6F2B, 0xC2FE, + 0x6F2D, 0xE4DD, + 0x6F2F, 0xE4F0, + 0x6F31, 0xCAFE, + 0x6F33, 0xD5C4, + 0x6F36, 0xE4F1, + 0x6F3E, 0xD1FA, + 0x6F46, 0xE4EB, + 0x6F47, 0xE4EC, + 0x6F4B, 0xE4F2, + 0x6F4D, 0xCEAB, + 0x6F58, 0xC5CB, + 0x6F5C, 0xC7B1, + 0x6F5E, 0xC2BA, + 0x6F62, 0xE4EA, + 0x6F66, 0xC1CA, + 0x6F6D, 0xCCB6, + 0x6F6E, 0xB3B1, + 0x6F72, 0xE4FB, + 0x6F74, 0xE4F3, + 0x6F78, 0xE4FA, + 0x6F7A, 0xE4FD, + 0x6F7C, 0xE4FC, + 0x6F84, 0xB3CE, + 0x6F88, 0xB3BA, + 0x6F89, 0xE4F7, + 0x6F8C, 0xE4F9, + 0x6F8D, 0xE4F8, + 0x6F8E, 0xC5EC, + 0x6F9C, 0xC0BD, + 0x6FA1, 0xD4E8, + 0x6FA7, 0xE5A2, + 0x6FB3, 0xB0C4, + 0x6FB6, 0xE5A4, + 0x6FB9, 0xE5A3, + 0x6FC0, 0xBCA4, + 0x6FC2, 0xE5A5, + 0x6FC9, 0xE5A1, + 0x6FD1, 0xE4FE, + 0x6FD2, 0xB1F4, + 0x6FDE, 0xE5A8, + 0x6FE0, 0xE5A9, + 0x6FE1, 0xE5A6, + 0x6FEE, 0xE5A7, + 0x6FEF, 0xE5AA, + 0x7011, 0xC6D9, + 0x701A, 0xE5AB, + 0x701B, 0xE5AD, + 0x7023, 0xE5AC, + 0x7035, 0xE5AF, + 0x7039, 0xE5AE, + 0x704C, 0xB9E0, + 0x704F, 0xE5B0, + 0x705E, 0xE5B1, + 0x706B, 0xBBF0, + 0x706C, 0xECE1, + 0x706D, 0xC3F0, + 0x706F, 0xB5C6, + 0x7070, 0xBBD2, + 0x7075, 0xC1E9, + 0x7076, 0xD4EE, + 0x7078, 0xBEC4, + 0x707C, 0xD7C6, + 0x707E, 0xD4D6, + 0x707F, 0xB2D3, + 0x7080, 0xECBE, + 0x7085, 0xEAC1, + 0x7089, 0xC2AF, + 0x708A, 0xB4B6, + 0x708E, 0xD1D7, + 0x7092, 0xB3B4, + 0x7094, 0xC8B2, + 0x7095, 0xBFBB, + 0x7096, 0xECC0, + 0x7099, 0xD6CB, + 0x709C, 0xECBF, + 0x709D, 0xECC1, + 0x70AB, 0xECC5, + 0x70AC, 0xBEE6, + 0x70AD, 0xCCBF, + 0x70AE, 0xC5DA, + 0x70AF, 0xBEBC, + 0x70B1, 0xECC6, + 0x70B3, 0xB1FE, + 0x70B7, 0xECC4, + 0x70B8, 0xD5A8, + 0x70B9, 0xB5E3, + 0x70BB, 0xECC2, + 0x70BC, 0xC1B6, + 0x70BD, 0xB3E3, + 0x70C0, 0xECC3, + 0x70C1, 0xCBB8, + 0x70C2, 0xC0C3, + 0x70C3, 0xCCFE, + 0x70C8, 0xC1D2, + 0x70CA, 0xECC8, + 0x70D8, 0xBAE6, + 0x70D9, 0xC0D3, + 0x70DB, 0xD6F2, + 0x70DF, 0xD1CC, + 0x70E4, 0xBFBE, + 0x70E6, 0xB7B3, + 0x70E7, 0xC9D5, + 0x70E8, 0xECC7, + 0x70E9, 0xBBE2, + 0x70EB, 0xCCCC, + 0x70EC, 0xBDFD, + 0x70ED, 0xC8C8, + 0x70EF, 0xCFA9, + 0x70F7, 0xCDE9, + 0x70F9, 0xC5EB, + 0x70FD, 0xB7E9, + 0x7109, 0xD1C9, + 0x710A, 0xBAB8, + 0x7110, 0xECC9, + 0x7113, 0xECCA, + 0x7115, 0xBBC0, + 0x7116, 0xECCB, + 0x7118, 0xECE2, + 0x7119, 0xB1BA, + 0x711A, 0xB7D9, + 0x7126, 0xBDB9, + 0x712F, 0xECCC, + 0x7130, 0xD1E6, + 0x7131, 0xECCD, + 0x7136, 0xC8BB, + 0x7145, 0xECD1, + 0x714A, 0xECD3, + 0x714C, 0xBBCD, + 0x714E, 0xBCE5, + 0x715C, 0xECCF, + 0x715E, 0xC9B7, + 0x7164, 0xC3BA, + 0x7166, 0xECE3, + 0x7167, 0xD5D5, + 0x7168, 0xECD0, + 0x716E, 0xD6F3, + 0x7172, 0xECD2, + 0x7173, 0xECCE, + 0x7178, 0xECD4, + 0x717A, 0xECD5, + 0x717D, 0xC9BF, + 0x7184, 0xCFA8, + 0x718A, 0xD0DC, + 0x718F, 0xD1AC, + 0x7194, 0xC8DB, + 0x7198, 0xECD6, + 0x7199, 0xCEF5, + 0x719F, 0xCAEC, + 0x71A0, 0xECDA, + 0x71A8, 0xECD9, + 0x71AC, 0xB0BE, + 0x71B3, 0xECD7, + 0x71B5, 0xECD8, + 0x71B9, 0xECE4, + 0x71C3, 0xC8BC, + 0x71CE, 0xC1C7, + 0x71D4, 0xECDC, + 0x71D5, 0xD1E0, + 0x71E0, 0xECDB, + 0x71E5, 0xD4EF, + 0x71E7, 0xECDD, + 0x71EE, 0xDBC6, + 0x71F9, 0xECDE, + 0x7206, 0xB1AC, + 0x721D, 0xECDF, + 0x7228, 0xECE0, + 0x722A, 0xD7A6, + 0x722C, 0xC5C0, + 0x7230, 0xEBBC, + 0x7231, 0xB0AE, + 0x7235, 0xBEF4, + 0x7236, 0xB8B8, + 0x7237, 0xD2AF, + 0x7238, 0xB0D6, + 0x7239, 0xB5F9, + 0x723B, 0xD8B3, + 0x723D, 0xCBAC, + 0x723F, 0xE3DD, + 0x7247, 0xC6AC, + 0x7248, 0xB0E6, + 0x724C, 0xC5C6, + 0x724D, 0xEBB9, + 0x7252, 0xEBBA, + 0x7256, 0xEBBB, + 0x7259, 0xD1C0, + 0x725B, 0xC5A3, + 0x725D, 0xEAF2, + 0x725F, 0xC4B2, + 0x7261, 0xC4B5, + 0x7262, 0xC0CE, + 0x7266, 0xEAF3, + 0x7267, 0xC4C1, + 0x7269, 0xCEEF, + 0x726E, 0xEAF0, + 0x726F, 0xEAF4, + 0x7272, 0xC9FC, + 0x7275, 0xC7A3, + 0x7279, 0xCCD8, + 0x727A, 0xCEFE, + 0x727E, 0xEAF5, + 0x727F, 0xEAF6, + 0x7280, 0xCFAC, + 0x7281, 0xC0E7, + 0x7284, 0xEAF7, + 0x728A, 0xB6BF, + 0x728B, 0xEAF8, + 0x728D, 0xEAF9, + 0x728F, 0xEAFA, + 0x7292, 0xEAFB, + 0x729F, 0xEAF1, + 0x72AC, 0xC8AE, + 0x72AD, 0xE1EB, + 0x72AF, 0xB7B8, + 0x72B0, 0xE1EC, + 0x72B4, 0xE1ED, + 0x72B6, 0xD7B4, + 0x72B7, 0xE1EE, + 0x72B8, 0xE1EF, + 0x72B9, 0xD3CC, + 0x72C1, 0xE1F1, + 0x72C2, 0xBFF1, + 0x72C3, 0xE1F0, + 0x72C4, 0xB5D2, + 0x72C8, 0xB1B7, + 0x72CD, 0xE1F3, + 0x72CE, 0xE1F2, + 0x72D0, 0xBAFC, + 0x72D2, 0xE1F4, + 0x72D7, 0xB9B7, + 0x72D9, 0xBED1, + 0x72DE, 0xC4FC, + 0x72E0, 0xBADD, + 0x72E1, 0xBDC6, + 0x72E8, 0xE1F5, + 0x72E9, 0xE1F7, + 0x72EC, 0xB6C0, + 0x72ED, 0xCFC1, + 0x72EE, 0xCAA8, + 0x72EF, 0xE1F6, + 0x72F0, 0xD5F8, + 0x72F1, 0xD3FC, + 0x72F2, 0xE1F8, + 0x72F3, 0xE1FC, + 0x72F4, 0xE1F9, + 0x72F7, 0xE1FA, + 0x72F8, 0xC0EA, + 0x72FA, 0xE1FE, + 0x72FB, 0xE2A1, + 0x72FC, 0xC0C7, + 0x7301, 0xE1FB, + 0x7303, 0xE1FD, + 0x730A, 0xE2A5, + 0x730E, 0xC1D4, + 0x7313, 0xE2A3, + 0x7315, 0xE2A8, + 0x7316, 0xB2FE, + 0x7317, 0xE2A2, + 0x731B, 0xC3CD, + 0x731C, 0xB2C2, + 0x731D, 0xE2A7, + 0x731E, 0xE2A6, + 0x7321, 0xE2A4, + 0x7322, 0xE2A9, + 0x7325, 0xE2AB, + 0x7329, 0xD0C9, + 0x732A, 0xD6ED, + 0x732B, 0xC3A8, + 0x732C, 0xE2AC, + 0x732E, 0xCFD7, + 0x7331, 0xE2AE, + 0x7334, 0xBAEF, + 0x7337, 0xE9E0, + 0x7338, 0xE2AD, + 0x7339, 0xE2AA, + 0x733E, 0xBBAB, + 0x733F, 0xD4B3, + 0x734D, 0xE2B0, + 0x7350, 0xE2AF, + 0x7352, 0xE9E1, + 0x7357, 0xE2B1, + 0x7360, 0xE2B2, + 0x736C, 0xE2B3, + 0x736D, 0xCCA1, + 0x736F, 0xE2B4, + 0x737E, 0xE2B5, + 0x7384, 0xD0FE, + 0x7387, 0xC2CA, + 0x7389, 0xD3F1, + 0x738B, 0xCDF5, + 0x738E, 0xE7E0, + 0x7391, 0xE7E1, + 0x7396, 0xBEC1, + 0x739B, 0xC2EA, + 0x739F, 0xE7E4, + 0x73A2, 0xE7E3, + 0x73A9, 0xCDE6, + 0x73AB, 0xC3B5, + 0x73AE, 0xE7E2, + 0x73AF, 0xBBB7, + 0x73B0, 0xCFD6, + 0x73B2, 0xC1E1, + 0x73B3, 0xE7E9, + 0x73B7, 0xE7E8, + 0x73BA, 0xE7F4, + 0x73BB, 0xB2A3, + 0x73C0, 0xE7EA, + 0x73C2, 0xE7E6, + 0x73C8, 0xE7EC, + 0x73C9, 0xE7EB, + 0x73CA, 0xC9BA, + 0x73CD, 0xD5E4, + 0x73CF, 0xE7E5, + 0x73D0, 0xB7A9, + 0x73D1, 0xE7E7, + 0x73D9, 0xE7EE, + 0x73DE, 0xE7F3, + 0x73E0, 0xD6E9, + 0x73E5, 0xE7ED, + 0x73E7, 0xE7F2, + 0x73E9, 0xE7F1, + 0x73ED, 0xB0E0, + 0x73F2, 0xE7F5, + 0x7403, 0xC7F2, + 0x7405, 0xC0C5, + 0x7406, 0xC0ED, + 0x7409, 0xC1F0, + 0x740A, 0xE7F0, + 0x740F, 0xE7F6, + 0x7410, 0xCBF6, + 0x741A, 0xE8A2, + 0x741B, 0xE8A1, + 0x7422, 0xD7C1, + 0x7425, 0xE7FA, + 0x7426, 0xE7F9, + 0x7428, 0xE7FB, + 0x742A, 0xE7F7, + 0x742C, 0xE7FE, + 0x742E, 0xE7FD, + 0x7430, 0xE7FC, + 0x7433, 0xC1D5, + 0x7434, 0xC7D9, + 0x7435, 0xC5FD, + 0x7436, 0xC5C3, + 0x743C, 0xC7ED, + 0x7441, 0xE8A3, + 0x7455, 0xE8A6, + 0x7457, 0xE8A5, + 0x7459, 0xE8A7, + 0x745A, 0xBAF7, + 0x745B, 0xE7F8, + 0x745C, 0xE8A4, + 0x745E, 0xC8F0, + 0x745F, 0xC9AA, + 0x746D, 0xE8A9, + 0x7470, 0xB9E5, + 0x7476, 0xD1FE, + 0x7477, 0xE8A8, + 0x747E, 0xE8AA, + 0x7480, 0xE8AD, + 0x7481, 0xE8AE, + 0x7483, 0xC1A7, + 0x7487, 0xE8AF, + 0x748B, 0xE8B0, + 0x748E, 0xE8AC, + 0x7490, 0xE8B4, + 0x749C, 0xE8AB, + 0x749E, 0xE8B1, + 0x74A7, 0xE8B5, + 0x74A8, 0xE8B2, + 0x74A9, 0xE8B3, + 0x74BA, 0xE8B7, + 0x74D2, 0xE8B6, + 0x74DC, 0xB9CF, + 0x74DE, 0xF0AC, + 0x74E0, 0xF0AD, + 0x74E2, 0xC6B0, + 0x74E3, 0xB0EA, + 0x74E4, 0xC8BF, + 0x74E6, 0xCDDF, + 0x74EE, 0xCECD, + 0x74EF, 0xEAB1, + 0x74F4, 0xEAB2, + 0x74F6, 0xC6BF, + 0x74F7, 0xB4C9, + 0x74FF, 0xEAB3, + 0x7504, 0xD5E7, + 0x750D, 0xDDF9, + 0x750F, 0xEAB4, + 0x7511, 0xEAB5, + 0x7513, 0xEAB6, + 0x7518, 0xB8CA, + 0x7519, 0xDFB0, + 0x751A, 0xC9F5, + 0x751C, 0xCCF0, + 0x751F, 0xC9FA, + 0x7525, 0xC9FB, + 0x7528, 0xD3C3, + 0x7529, 0xCBA6, + 0x752B, 0xB8A6, + 0x752C, 0xF0AE, + 0x752D, 0xB1C2, + 0x752F, 0xE5B8, + 0x7530, 0xCCEF, + 0x7531, 0xD3C9, + 0x7532, 0xBCD7, + 0x7533, 0xC9EA, + 0x7535, 0xB5E7, + 0x7537, 0xC4D0, + 0x7538, 0xB5E9, + 0x753A, 0xEEAE, + 0x753B, 0xBBAD, + 0x753E, 0xE7DE, + 0x7540, 0xEEAF, + 0x7545, 0xB3A9, + 0x7548, 0xEEB2, + 0x754B, 0xEEB1, + 0x754C, 0xBDE7, + 0x754E, 0xEEB0, + 0x754F, 0xCEB7, + 0x7554, 0xC5CF, + 0x7559, 0xC1F4, + 0x755A, 0xDBCE, + 0x755B, 0xEEB3, + 0x755C, 0xD0F3, + 0x7565, 0xC2D4, + 0x7566, 0xC6E8, + 0x756A, 0xB7AC, + 0x7572, 0xEEB4, + 0x7574, 0xB3EB, + 0x7578, 0xBBFB, + 0x7579, 0xEEB5, + 0x757F, 0xE7DC, + 0x7583, 0xEEB6, + 0x7586, 0xBDAE, + 0x758B, 0xF1E2, + 0x758F, 0xCAE8, + 0x7591, 0xD2C9, + 0x7592, 0xF0DA, + 0x7594, 0xF0DB, + 0x7596, 0xF0DC, + 0x7597, 0xC1C6, + 0x7599, 0xB8ED, + 0x759A, 0xBECE, + 0x759D, 0xF0DE, + 0x759F, 0xC5B1, + 0x75A0, 0xF0DD, + 0x75A1, 0xD1F1, + 0x75A3, 0xF0E0, + 0x75A4, 0xB0CC, + 0x75A5, 0xBDEA, + 0x75AB, 0xD2DF, + 0x75AC, 0xF0DF, + 0x75AE, 0xB4AF, + 0x75AF, 0xB7E8, + 0x75B0, 0xF0E6, + 0x75B1, 0xF0E5, + 0x75B2, 0xC6A3, + 0x75B3, 0xF0E1, + 0x75B4, 0xF0E2, + 0x75B5, 0xB4C3, + 0x75B8, 0xF0E3, + 0x75B9, 0xD5EE, + 0x75BC, 0xCCDB, + 0x75BD, 0xBED2, + 0x75BE, 0xBCB2, + 0x75C2, 0xF0E8, + 0x75C3, 0xF0E7, + 0x75C4, 0xF0E4, + 0x75C5, 0xB2A1, + 0x75C7, 0xD6A2, + 0x75C8, 0xD3B8, + 0x75C9, 0xBEB7, + 0x75CA, 0xC8AC, + 0x75CD, 0xF0EA, + 0x75D2, 0xD1F7, + 0x75D4, 0xD6CC, + 0x75D5, 0xBADB, + 0x75D6, 0xF0E9, + 0x75D8, 0xB6BB, + 0x75DB, 0xCDB4, + 0x75DE, 0xC6A6, + 0x75E2, 0xC1A1, + 0x75E3, 0xF0EB, + 0x75E4, 0xF0EE, + 0x75E6, 0xF0ED, + 0x75E7, 0xF0F0, + 0x75E8, 0xF0EC, + 0x75EA, 0xBBBE, + 0x75EB, 0xF0EF, + 0x75F0, 0xCCB5, + 0x75F1, 0xF0F2, + 0x75F4, 0xB3D5, + 0x75F9, 0xB1D4, + 0x75FC, 0xF0F3, + 0x75FF, 0xF0F4, + 0x7600, 0xF0F6, + 0x7601, 0xB4E1, + 0x7603, 0xF0F1, + 0x7605, 0xF0F7, + 0x760A, 0xF0FA, + 0x760C, 0xF0F8, + 0x7610, 0xF0F5, + 0x7615, 0xF0FD, + 0x7617, 0xF0F9, + 0x7618, 0xF0FC, + 0x7619, 0xF0FE, + 0x761B, 0xF1A1, + 0x761F, 0xCEC1, + 0x7620, 0xF1A4, + 0x7622, 0xF1A3, + 0x7624, 0xC1F6, + 0x7625, 0xF0FB, + 0x7626, 0xCADD, + 0x7629, 0xB4F1, + 0x762A, 0xB1F1, + 0x762B, 0xCCB1, + 0x762D, 0xF1A6, + 0x7630, 0xF1A7, + 0x7633, 0xF1AC, + 0x7634, 0xD5CE, + 0x7635, 0xF1A9, + 0x7638, 0xC8B3, + 0x763C, 0xF1A2, + 0x763E, 0xF1AB, + 0x763F, 0xF1A8, + 0x7640, 0xF1A5, + 0x7643, 0xF1AA, + 0x764C, 0xB0A9, + 0x764D, 0xF1AD, + 0x7654, 0xF1AF, + 0x7656, 0xF1B1, + 0x765C, 0xF1B0, + 0x765E, 0xF1AE, + 0x7663, 0xD1A2, + 0x766B, 0xF1B2, + 0x766F, 0xF1B3, + 0x7678, 0xB9EF, + 0x767B, 0xB5C7, + 0x767D, 0xB0D7, + 0x767E, 0xB0D9, + 0x7682, 0xD4ED, + 0x7684, 0xB5C4, + 0x7686, 0xBDD4, + 0x7687, 0xBBCA, + 0x7688, 0xF0A7, + 0x768B, 0xB8DE, + 0x768E, 0xF0A8, + 0x7691, 0xB0A8, + 0x7693, 0xF0A9, + 0x7696, 0xCDEE, + 0x7699, 0xF0AA, + 0x76A4, 0xF0AB, + 0x76AE, 0xC6A4, + 0x76B1, 0xD6E5, + 0x76B2, 0xF1E4, + 0x76B4, 0xF1E5, + 0x76BF, 0xC3F3, + 0x76C2, 0xD3DB, + 0x76C5, 0xD6D1, + 0x76C6, 0xC5E8, + 0x76C8, 0xD3AF, + 0x76CA, 0xD2E6, + 0x76CD, 0xEEC1, + 0x76CE, 0xB0BB, + 0x76CF, 0xD5B5, + 0x76D0, 0xD1CE, + 0x76D1, 0xBCE0, + 0x76D2, 0xBAD0, + 0x76D4, 0xBFF8, + 0x76D6, 0xB8C7, + 0x76D7, 0xB5C1, + 0x76D8, 0xC5CC, + 0x76DB, 0xCAA2, + 0x76DF, 0xC3CB, + 0x76E5, 0xEEC2, + 0x76EE, 0xC4BF, + 0x76EF, 0xB6A2, + 0x76F1, 0xEDEC, + 0x76F2, 0xC3A4, + 0x76F4, 0xD6B1, + 0x76F8, 0xCFE0, + 0x76F9, 0xEDEF, + 0x76FC, 0xC5CE, + 0x76FE, 0xB6DC, + 0x7701, 0xCAA1, + 0x7704, 0xEDED, + 0x7707, 0xEDF0, + 0x7708, 0xEDF1, + 0x7709, 0xC3BC, + 0x770B, 0xBFB4, + 0x770D, 0xEDEE, + 0x7719, 0xEDF4, + 0x771A, 0xEDF2, + 0x771F, 0xD5E6, + 0x7720, 0xC3DF, + 0x7722, 0xEDF3, + 0x7726, 0xEDF6, + 0x7728, 0xD5A3, + 0x7729, 0xD1A3, + 0x772D, 0xEDF5, + 0x772F, 0xC3D0, + 0x7735, 0xEDF7, + 0x7736, 0xBFF4, + 0x7737, 0xBEEC, + 0x7738, 0xEDF8, + 0x773A, 0xCCF7, + 0x773C, 0xD1DB, + 0x7740, 0xD7C5, + 0x7741, 0xD5F6, + 0x7743, 0xEDFC, + 0x7747, 0xEDFB, + 0x7750, 0xEDF9, + 0x7751, 0xEDFA, + 0x775A, 0xEDFD, + 0x775B, 0xBEA6, + 0x7761, 0xCBAF, + 0x7762, 0xEEA1, + 0x7763, 0xB6BD, + 0x7765, 0xEEA2, + 0x7766, 0xC4C0, + 0x7768, 0xEDFE, + 0x776B, 0xBDDE, + 0x776C, 0xB2C7, + 0x7779, 0xB6C3, + 0x777D, 0xEEA5, + 0x777E, 0xD8BA, + 0x777F, 0xEEA3, + 0x7780, 0xEEA6, + 0x7784, 0xC3E9, + 0x7785, 0xB3F2, + 0x778C, 0xEEA7, + 0x778D, 0xEEA4, + 0x778E, 0xCFB9, + 0x7791, 0xEEA8, + 0x7792, 0xC2F7, + 0x779F, 0xEEA9, + 0x77A0, 0xEEAA, + 0x77A2, 0xDEAB, + 0x77A5, 0xC6B3, + 0x77A7, 0xC7C6, + 0x77A9, 0xD6F5, + 0x77AA, 0xB5C9, + 0x77AC, 0xCBB2, + 0x77B0, 0xEEAB, + 0x77B3, 0xCDAB, + 0x77B5, 0xEEAC, + 0x77BB, 0xD5B0, + 0x77BD, 0xEEAD, + 0x77BF, 0xF6C4, + 0x77CD, 0xDBC7, + 0x77D7, 0xB4A3, + 0x77DB, 0xC3AC, + 0x77DC, 0xF1E6, + 0x77E2, 0xCAB8, + 0x77E3, 0xD2D3, + 0x77E5, 0xD6AA, + 0x77E7, 0xEFF2, + 0x77E9, 0xBED8, + 0x77EB, 0xBDC3, + 0x77EC, 0xEFF3, + 0x77ED, 0xB6CC, + 0x77EE, 0xB0AB, + 0x77F3, 0xCAAF, + 0x77F6, 0xEDB6, + 0x77F8, 0xEDB7, + 0x77FD, 0xCEF9, + 0x77FE, 0xB7AF, + 0x77FF, 0xBFF3, + 0x7800, 0xEDB8, + 0x7801, 0xC2EB, + 0x7802, 0xC9B0, + 0x7809, 0xEDB9, + 0x780C, 0xC6F6, + 0x780D, 0xBFB3, + 0x7811, 0xEDBC, + 0x7812, 0xC5F8, + 0x7814, 0xD1D0, + 0x7816, 0xD7A9, + 0x7817, 0xEDBA, + 0x7818, 0xEDBB, + 0x781A, 0xD1E2, + 0x781C, 0xEDBF, + 0x781D, 0xEDC0, + 0x781F, 0xEDC4, + 0x7823, 0xEDC8, + 0x7825, 0xEDC6, + 0x7826, 0xEDCE, + 0x7827, 0xD5E8, + 0x7829, 0xEDC9, + 0x782C, 0xEDC7, + 0x782D, 0xEDBE, + 0x7830, 0xC5E9, + 0x7834, 0xC6C6, + 0x7837, 0xC9E9, + 0x7838, 0xD4D2, + 0x7839, 0xEDC1, + 0x783A, 0xEDC2, + 0x783B, 0xEDC3, + 0x783C, 0xEDC5, + 0x783E, 0xC0F9, + 0x7840, 0xB4A1, + 0x7845, 0xB9E8, + 0x7847, 0xEDD0, + 0x784C, 0xEDD1, + 0x784E, 0xEDCA, + 0x7850, 0xEDCF, + 0x7852, 0xCEF8, + 0x7855, 0xCBB6, + 0x7856, 0xEDCC, + 0x7857, 0xEDCD, + 0x785D, 0xCFF5, + 0x786A, 0xEDD2, + 0x786B, 0xC1F2, + 0x786C, 0xD3B2, + 0x786D, 0xEDCB, + 0x786E, 0xC8B7, + 0x7877, 0xBCEF, + 0x787C, 0xC5F0, + 0x7887, 0xEDD6, + 0x7889, 0xB5EF, + 0x788C, 0xC2B5, + 0x788D, 0xB0AD, + 0x788E, 0xCBE9, + 0x7891, 0xB1AE, + 0x7893, 0xEDD4, + 0x7897, 0xCDEB, + 0x7898, 0xB5E2, + 0x789A, 0xEDD5, + 0x789B, 0xEDD3, + 0x789C, 0xEDD7, + 0x789F, 0xB5FA, + 0x78A1, 0xEDD8, + 0x78A3, 0xEDD9, + 0x78A5, 0xEDDC, + 0x78A7, 0xB1CC, + 0x78B0, 0xC5F6, + 0x78B1, 0xBCEE, + 0x78B2, 0xEDDA, + 0x78B3, 0xCCBC, + 0x78B4, 0xB2EA, + 0x78B9, 0xEDDB, + 0x78BE, 0xC4EB, + 0x78C1, 0xB4C5, + 0x78C5, 0xB0F5, + 0x78C9, 0xEDDF, + 0x78CA, 0xC0DA, + 0x78CB, 0xB4E8, + 0x78D0, 0xC5CD, + 0x78D4, 0xEDDD, + 0x78D5, 0xBFC4, + 0x78D9, 0xEDDE, + 0x78E8, 0xC4A5, + 0x78EC, 0xEDE0, + 0x78F2, 0xEDE1, + 0x78F4, 0xEDE3, + 0x78F7, 0xC1D7, + 0x78FA, 0xBBC7, + 0x7901, 0xBDB8, + 0x7905, 0xEDE2, + 0x7913, 0xEDE4, + 0x791E, 0xEDE6, + 0x7924, 0xEDE5, + 0x7934, 0xEDE7, + 0x793A, 0xCABE, + 0x793B, 0xECEA, + 0x793C, 0xC0F1, + 0x793E, 0xC9E7, + 0x7940, 0xECEB, + 0x7941, 0xC6EE, + 0x7946, 0xECEC, + 0x7948, 0xC6ED, + 0x7949, 0xECED, + 0x7953, 0xECF0, + 0x7956, 0xD7E6, + 0x7957, 0xECF3, + 0x795A, 0xECF1, + 0x795B, 0xECEE, + 0x795C, 0xECEF, + 0x795D, 0xD7A3, + 0x795E, 0xC9F1, + 0x795F, 0xCBEE, + 0x7960, 0xECF4, + 0x7962, 0xECF2, + 0x7965, 0xCFE9, + 0x7967, 0xECF6, + 0x7968, 0xC6B1, + 0x796D, 0xBCC0, + 0x796F, 0xECF5, + 0x7977, 0xB5BB, + 0x7978, 0xBBF6, + 0x797A, 0xECF7, + 0x7980, 0xD9F7, + 0x7981, 0xBDFB, + 0x7984, 0xC2BB, + 0x7985, 0xECF8, + 0x798A, 0xECF9, + 0x798F, 0xB8A3, + 0x799A, 0xECFA, + 0x79A7, 0xECFB, + 0x79B3, 0xECFC, + 0x79B9, 0xD3ED, + 0x79BA, 0xD8AE, + 0x79BB, 0xC0EB, + 0x79BD, 0xC7DD, + 0x79BE, 0xBACC, + 0x79C0, 0xD0E3, + 0x79C1, 0xCBBD, + 0x79C3, 0xCDBA, + 0x79C6, 0xB8D1, + 0x79C9, 0xB1FC, + 0x79CB, 0xC7EF, + 0x79CD, 0xD6D6, + 0x79D1, 0xBFC6, + 0x79D2, 0xC3EB, + 0x79D5, 0xEFF5, + 0x79D8, 0xC3D8, + 0x79DF, 0xD7E2, + 0x79E3, 0xEFF7, + 0x79E4, 0xB3D3, + 0x79E6, 0xC7D8, + 0x79E7, 0xD1ED, + 0x79E9, 0xD6C8, + 0x79EB, 0xEFF8, + 0x79ED, 0xEFF6, + 0x79EF, 0xBBFD, + 0x79F0, 0xB3C6, + 0x79F8, 0xBDD5, + 0x79FB, 0xD2C6, + 0x79FD, 0xBBE0, + 0x7A00, 0xCFA1, + 0x7A02, 0xEFFC, + 0x7A03, 0xEFFB, + 0x7A06, 0xEFF9, + 0x7A0B, 0xB3CC, + 0x7A0D, 0xC9D4, + 0x7A0E, 0xCBB0, + 0x7A14, 0xEFFE, + 0x7A17, 0xB0DE, + 0x7A1A, 0xD6C9, + 0x7A1E, 0xEFFD, + 0x7A20, 0xB3ED, + 0x7A23, 0xF6D5, + 0x7A33, 0xCEC8, + 0x7A37, 0xF0A2, + 0x7A39, 0xF0A1, + 0x7A3B, 0xB5BE, + 0x7A3C, 0xBCDA, + 0x7A3D, 0xBBFC, + 0x7A3F, 0xB8E5, + 0x7A46, 0xC4C2, + 0x7A51, 0xF0A3, + 0x7A57, 0xCBEB, + 0x7A70, 0xF0A6, + 0x7A74, 0xD1A8, + 0x7A76, 0xBEBF, + 0x7A77, 0xC7EE, + 0x7A78, 0xF1B6, + 0x7A79, 0xF1B7, + 0x7A7A, 0xBFD5, + 0x7A7F, 0xB4A9, + 0x7A80, 0xF1B8, + 0x7A81, 0xCDBB, + 0x7A83, 0xC7D4, + 0x7A84, 0xD5AD, + 0x7A86, 0xF1B9, + 0x7A88, 0xF1BA, + 0x7A8D, 0xC7CF, + 0x7A91, 0xD2A4, + 0x7A92, 0xD6CF, + 0x7A95, 0xF1BB, + 0x7A96, 0xBDD1, + 0x7A97, 0xB4B0, + 0x7A98, 0xBEBD, + 0x7A9C, 0xB4DC, + 0x7A9D, 0xCED1, + 0x7A9F, 0xBFDF, + 0x7AA0, 0xF1BD, + 0x7AA5, 0xBFFA, + 0x7AA6, 0xF1BC, + 0x7AA8, 0xF1BF, + 0x7AAC, 0xF1BE, + 0x7AAD, 0xF1C0, + 0x7AB3, 0xF1C1, + 0x7ABF, 0xC1FE, + 0x7ACB, 0xC1A2, + 0x7AD6, 0xCAFA, + 0x7AD9, 0xD5BE, + 0x7ADE, 0xBEBA, + 0x7ADF, 0xBEB9, + 0x7AE0, 0xD5C2, + 0x7AE3, 0xBFA2, + 0x7AE5, 0xCDAF, + 0x7AE6, 0xF1B5, + 0x7AED, 0xBDDF, + 0x7AEF, 0xB6CB, + 0x7AF9, 0xD6F1, + 0x7AFA, 0xF3C3, + 0x7AFD, 0xF3C4, + 0x7AFF, 0xB8CD, + 0x7B03, 0xF3C6, + 0x7B04, 0xF3C7, + 0x7B06, 0xB0CA, + 0x7B08, 0xF3C5, + 0x7B0A, 0xF3C9, + 0x7B0B, 0xCBF1, + 0x7B0F, 0xF3CB, + 0x7B11, 0xD0A6, + 0x7B14, 0xB1CA, + 0x7B15, 0xF3C8, + 0x7B19, 0xF3CF, + 0x7B1B, 0xB5D1, + 0x7B1E, 0xF3D7, + 0x7B20, 0xF3D2, + 0x7B24, 0xF3D4, + 0x7B25, 0xF3D3, + 0x7B26, 0xB7FB, + 0x7B28, 0xB1BF, + 0x7B2A, 0xF3CE, + 0x7B2B, 0xF3CA, + 0x7B2C, 0xB5DA, + 0x7B2E, 0xF3D0, + 0x7B31, 0xF3D1, + 0x7B33, 0xF3D5, + 0x7B38, 0xF3CD, + 0x7B3A, 0xBCE3, + 0x7B3C, 0xC1FD, + 0x7B3E, 0xF3D6, + 0x7B45, 0xF3DA, + 0x7B47, 0xF3CC, + 0x7B49, 0xB5C8, + 0x7B4B, 0xBDEE, + 0x7B4C, 0xF3DC, + 0x7B4F, 0xB7A4, + 0x7B50, 0xBFF0, + 0x7B51, 0xD6FE, + 0x7B52, 0xCDB2, + 0x7B54, 0xB4F0, + 0x7B56, 0xB2DF, + 0x7B58, 0xF3D8, + 0x7B5A, 0xF3D9, + 0x7B5B, 0xC9B8, + 0x7B5D, 0xF3DD, + 0x7B60, 0xF3DE, + 0x7B62, 0xF3E1, + 0x7B6E, 0xF3DF, + 0x7B71, 0xF3E3, + 0x7B72, 0xF3E2, + 0x7B75, 0xF3DB, + 0x7B77, 0xBFEA, + 0x7B79, 0xB3EF, + 0x7B7B, 0xF3E0, + 0x7B7E, 0xC7A9, + 0x7B80, 0xBCF2, + 0x7B85, 0xF3EB, + 0x7B8D, 0xB9BF, + 0x7B90, 0xF3E4, + 0x7B94, 0xB2AD, + 0x7B95, 0xBBFE, + 0x7B97, 0xCBE3, + 0x7B9C, 0xF3ED, + 0x7B9D, 0xF3E9, + 0x7BA1, 0xB9DC, + 0x7BA2, 0xF3EE, + 0x7BA6, 0xF3E5, + 0x7BA7, 0xF3E6, + 0x7BA8, 0xF3EA, + 0x7BA9, 0xC2E1, + 0x7BAA, 0xF3EC, + 0x7BAB, 0xF3EF, + 0x7BAC, 0xF3E8, + 0x7BAD, 0xBCFD, + 0x7BB1, 0xCFE4, + 0x7BB4, 0xF3F0, + 0x7BB8, 0xF3E7, + 0x7BC1, 0xF3F2, + 0x7BC6, 0xD7AD, + 0x7BC7, 0xC6AA, + 0x7BCC, 0xF3F3, + 0x7BD1, 0xF3F1, + 0x7BD3, 0xC2A8, + 0x7BD9, 0xB8DD, + 0x7BDA, 0xF3F5, + 0x7BDD, 0xF3F4, + 0x7BE1, 0xB4DB, + 0x7BE5, 0xF3F6, + 0x7BE6, 0xF3F7, + 0x7BEA, 0xF3F8, + 0x7BEE, 0xC0BA, + 0x7BF1, 0xC0E9, + 0x7BF7, 0xC5F1, + 0x7BFC, 0xF3FB, + 0x7BFE, 0xF3FA, + 0x7C07, 0xB4D8, + 0x7C0B, 0xF3FE, + 0x7C0C, 0xF3F9, + 0x7C0F, 0xF3FC, + 0x7C16, 0xF3FD, + 0x7C1F, 0xF4A1, + 0x7C26, 0xF4A3, + 0x7C27, 0xBBC9, + 0x7C2A, 0xF4A2, + 0x7C38, 0xF4A4, + 0x7C3F, 0xB2BE, + 0x7C40, 0xF4A6, + 0x7C41, 0xF4A5, + 0x7C4D, 0xBCAE, + 0x7C73, 0xC3D7, + 0x7C74, 0xD9E1, + 0x7C7B, 0xC0E0, + 0x7C7C, 0xF4CC, + 0x7C7D, 0xD7D1, + 0x7C89, 0xB7DB, + 0x7C91, 0xF4CE, + 0x7C92, 0xC1A3, + 0x7C95, 0xC6C9, + 0x7C97, 0xB4D6, + 0x7C98, 0xD5B3, + 0x7C9C, 0xF4D0, + 0x7C9D, 0xF4CF, + 0x7C9E, 0xF4D1, + 0x7C9F, 0xCBDA, + 0x7CA2, 0xF4D2, + 0x7CA4, 0xD4C1, + 0x7CA5, 0xD6E0, + 0x7CAA, 0xB7E0, + 0x7CAE, 0xC1B8, + 0x7CB1, 0xC1BB, + 0x7CB2, 0xF4D3, + 0x7CB3, 0xBEAC, + 0x7CB9, 0xB4E2, + 0x7CBC, 0xF4D4, + 0x7CBD, 0xF4D5, + 0x7CBE, 0xBEAB, + 0x7CC1, 0xF4D6, + 0x7CC5, 0xF4DB, + 0x7CC7, 0xF4D7, + 0x7CC8, 0xF4DA, + 0x7CCA, 0xBAFD, + 0x7CCC, 0xF4D8, + 0x7CCD, 0xF4D9, + 0x7CD5, 0xB8E2, + 0x7CD6, 0xCCC7, + 0x7CD7, 0xF4DC, + 0x7CD9, 0xB2DA, + 0x7CDC, 0xC3D3, + 0x7CDF, 0xD4E3, + 0x7CE0, 0xBFB7, + 0x7CE8, 0xF4DD, + 0x7CEF, 0xC5B4, + 0x7CF8, 0xF4E9, + 0x7CFB, 0xCFB5, + 0x7D0A, 0xCEC9, + 0x7D20, 0xCBD8, + 0x7D22, 0xCBF7, + 0x7D27, 0xBDF4, + 0x7D2B, 0xD7CF, + 0x7D2F, 0xC0DB, + 0x7D6E, 0xD0F5, + 0x7D77, 0xF4EA, + 0x7DA6, 0xF4EB, + 0x7DAE, 0xF4EC, + 0x7E3B, 0xF7E3, + 0x7E41, 0xB7B1, + 0x7E47, 0xF4ED, + 0x7E82, 0xD7EB, + 0x7E9B, 0xF4EE, + 0x7E9F, 0xE6F9, + 0x7EA0, 0xBEC0, + 0x7EA1, 0xE6FA, + 0x7EA2, 0xBAEC, + 0x7EA3, 0xE6FB, + 0x7EA4, 0xCFCB, + 0x7EA5, 0xE6FC, + 0x7EA6, 0xD4BC, + 0x7EA7, 0xBCB6, + 0x7EA8, 0xE6FD, + 0x7EA9, 0xE6FE, + 0x7EAA, 0xBCCD, + 0x7EAB, 0xC8D2, + 0x7EAC, 0xCEB3, + 0x7EAD, 0xE7A1, + 0x7EAF, 0xB4BF, + 0x7EB0, 0xE7A2, + 0x7EB1, 0xC9B4, + 0x7EB2, 0xB8D9, + 0x7EB3, 0xC4C9, + 0x7EB5, 0xD7DD, + 0x7EB6, 0xC2DA, + 0x7EB7, 0xB7D7, + 0x7EB8, 0xD6BD, + 0x7EB9, 0xCEC6, + 0x7EBA, 0xB7C4, + 0x7EBD, 0xC5A6, + 0x7EBE, 0xE7A3, + 0x7EBF, 0xCFDF, + 0x7EC0, 0xE7A4, + 0x7EC1, 0xE7A5, + 0x7EC2, 0xE7A6, + 0x7EC3, 0xC1B7, + 0x7EC4, 0xD7E9, + 0x7EC5, 0xC9F0, + 0x7EC6, 0xCFB8, + 0x7EC7, 0xD6AF, + 0x7EC8, 0xD6D5, + 0x7EC9, 0xE7A7, + 0x7ECA, 0xB0ED, + 0x7ECB, 0xE7A8, + 0x7ECC, 0xE7A9, + 0x7ECD, 0xC9DC, + 0x7ECE, 0xD2EF, + 0x7ECF, 0xBEAD, + 0x7ED0, 0xE7AA, + 0x7ED1, 0xB0F3, + 0x7ED2, 0xC8DE, + 0x7ED3, 0xBDE1, + 0x7ED4, 0xE7AB, + 0x7ED5, 0xC8C6, + 0x7ED7, 0xE7AC, + 0x7ED8, 0xBBE6, + 0x7ED9, 0xB8F8, + 0x7EDA, 0xD1A4, + 0x7EDB, 0xE7AD, + 0x7EDC, 0xC2E7, + 0x7EDD, 0xBEF8, + 0x7EDE, 0xBDCA, + 0x7EDF, 0xCDB3, + 0x7EE0, 0xE7AE, + 0x7EE1, 0xE7AF, + 0x7EE2, 0xBEEE, + 0x7EE3, 0xD0E5, + 0x7EE5, 0xCBE7, + 0x7EE6, 0xCCD0, + 0x7EE7, 0xBCCC, + 0x7EE8, 0xE7B0, + 0x7EE9, 0xBCA8, + 0x7EEA, 0xD0F7, + 0x7EEB, 0xE7B1, + 0x7EED, 0xD0F8, + 0x7EEE, 0xE7B2, + 0x7EEF, 0xE7B3, + 0x7EF0, 0xB4C2, + 0x7EF1, 0xE7B4, + 0x7EF2, 0xE7B5, + 0x7EF3, 0xC9FE, + 0x7EF4, 0xCEAC, + 0x7EF5, 0xC3E0, + 0x7EF6, 0xE7B7, + 0x7EF7, 0xB1C1, + 0x7EF8, 0xB3F1, + 0x7EFA, 0xE7B8, + 0x7EFB, 0xE7B9, + 0x7EFC, 0xD7DB, + 0x7EFD, 0xD5C0, + 0x7EFE, 0xE7BA, + 0x7EFF, 0xC2CC, + 0x7F00, 0xD7BA, + 0x7F01, 0xE7BB, + 0x7F02, 0xE7BC, + 0x7F03, 0xE7BD, + 0x7F04, 0xBCEA, + 0x7F05, 0xC3E5, + 0x7F06, 0xC0C2, + 0x7F07, 0xE7BE, + 0x7F08, 0xE7BF, + 0x7F09, 0xBCA9, + 0x7F0B, 0xE7C0, + 0x7F0C, 0xE7C1, + 0x7F0D, 0xE7B6, + 0x7F0E, 0xB6D0, + 0x7F0F, 0xE7C2, + 0x7F11, 0xE7C3, + 0x7F12, 0xE7C4, + 0x7F13, 0xBBBA, + 0x7F14, 0xB5DE, + 0x7F15, 0xC2C6, + 0x7F16, 0xB1E0, + 0x7F17, 0xE7C5, + 0x7F18, 0xD4B5, + 0x7F19, 0xE7C6, + 0x7F1A, 0xB8BF, + 0x7F1B, 0xE7C8, + 0x7F1C, 0xE7C7, + 0x7F1D, 0xB7EC, + 0x7F1F, 0xE7C9, + 0x7F20, 0xB2F8, + 0x7F21, 0xE7CA, + 0x7F22, 0xE7CB, + 0x7F23, 0xE7CC, + 0x7F24, 0xE7CD, + 0x7F25, 0xE7CE, + 0x7F26, 0xE7CF, + 0x7F27, 0xE7D0, + 0x7F28, 0xD3A7, + 0x7F29, 0xCBF5, + 0x7F2A, 0xE7D1, + 0x7F2B, 0xE7D2, + 0x7F2C, 0xE7D3, + 0x7F2D, 0xE7D4, + 0x7F2E, 0xC9C9, + 0x7F2F, 0xE7D5, + 0x7F30, 0xE7D6, + 0x7F31, 0xE7D7, + 0x7F32, 0xE7D8, + 0x7F33, 0xE7D9, + 0x7F34, 0xBDC9, + 0x7F35, 0xE7DA, + 0x7F36, 0xF3BE, + 0x7F38, 0xB8D7, + 0x7F3A, 0xC8B1, + 0x7F42, 0xF3BF, + 0x7F44, 0xF3C0, + 0x7F45, 0xF3C1, + 0x7F50, 0xB9DE, + 0x7F51, 0xCDF8, + 0x7F54, 0xD8E8, + 0x7F55, 0xBAB1, + 0x7F57, 0xC2DE, + 0x7F58, 0xEEB7, + 0x7F5A, 0xB7A3, + 0x7F5F, 0xEEB9, + 0x7F61, 0xEEB8, + 0x7F62, 0xB0D5, + 0x7F68, 0xEEBB, + 0x7F69, 0xD5D6, + 0x7F6A, 0xD7EF, + 0x7F6E, 0xD6C3, + 0x7F71, 0xEEBD, + 0x7F72, 0xCAF0, + 0x7F74, 0xEEBC, + 0x7F79, 0xEEBE, + 0x7F7E, 0xEEC0, + 0x7F81, 0xEEBF, + 0x7F8A, 0xD1F2, + 0x7F8C, 0xC7BC, + 0x7F8E, 0xC3C0, + 0x7F94, 0xB8E1, + 0x7F9A, 0xC1E7, + 0x7F9D, 0xF4C6, + 0x7F9E, 0xD0DF, + 0x7F9F, 0xF4C7, + 0x7FA1, 0xCFDB, + 0x7FA4, 0xC8BA, + 0x7FA7, 0xF4C8, + 0x7FAF, 0xF4C9, + 0x7FB0, 0xF4CA, + 0x7FB2, 0xF4CB, + 0x7FB8, 0xD9FA, + 0x7FB9, 0xB8FE, + 0x7FBC, 0xE5F1, + 0x7FBD, 0xD3F0, + 0x7FBF, 0xF4E0, + 0x7FC1, 0xCECC, + 0x7FC5, 0xB3E1, + 0x7FCA, 0xF1B4, + 0x7FCC, 0xD2EE, + 0x7FCE, 0xF4E1, + 0x7FD4, 0xCFE8, + 0x7FD5, 0xF4E2, + 0x7FD8, 0xC7CC, + 0x7FDF, 0xB5D4, + 0x7FE0, 0xB4E4, + 0x7FE1, 0xF4E4, + 0x7FE5, 0xF4E3, + 0x7FE6, 0xF4E5, + 0x7FE9, 0xF4E6, + 0x7FEE, 0xF4E7, + 0x7FF0, 0xBAB2, + 0x7FF1, 0xB0BF, + 0x7FF3, 0xF4E8, + 0x7FFB, 0xB7AD, + 0x7FFC, 0xD2ED, + 0x8000, 0xD2AB, + 0x8001, 0xC0CF, + 0x8003, 0xBFBC, + 0x8004, 0xEBA3, + 0x8005, 0xD5DF, + 0x8006, 0xEAC8, + 0x800B, 0xF1F3, + 0x800C, 0xB6F8, + 0x800D, 0xCBA3, + 0x8010, 0xC4CD, + 0x8012, 0xF1E7, + 0x8014, 0xF1E8, + 0x8015, 0xB8FB, + 0x8016, 0xF1E9, + 0x8017, 0xBAC4, + 0x8018, 0xD4C5, + 0x8019, 0xB0D2, + 0x801C, 0xF1EA, + 0x8020, 0xF1EB, + 0x8022, 0xF1EC, + 0x8025, 0xF1ED, + 0x8026, 0xF1EE, + 0x8027, 0xF1EF, + 0x8028, 0xF1F1, + 0x8029, 0xF1F0, + 0x802A, 0xC5D5, + 0x8031, 0xF1F2, + 0x8033, 0xB6FA, + 0x8035, 0xF1F4, + 0x8036, 0xD2AE, + 0x8037, 0xDEC7, + 0x8038, 0xCBCA, + 0x803B, 0xB3DC, + 0x803D, 0xB5A2, + 0x803F, 0xB9A2, + 0x8042, 0xC4F4, + 0x8043, 0xF1F5, + 0x8046, 0xF1F6, + 0x804A, 0xC1C4, + 0x804B, 0xC1FB, + 0x804C, 0xD6B0, + 0x804D, 0xF1F7, + 0x8052, 0xF1F8, + 0x8054, 0xC1AA, + 0x8058, 0xC6B8, + 0x805A, 0xBEDB, + 0x8069, 0xF1F9, + 0x806A, 0xB4CF, + 0x8071, 0xF1FA, + 0x807F, 0xEDB2, + 0x8080, 0xEDB1, + 0x8083, 0xCBE0, + 0x8084, 0xD2DE, + 0x8086, 0xCBC1, + 0x8087, 0xD5D8, + 0x8089, 0xC8E2, + 0x808B, 0xC0DF, + 0x808C, 0xBCA1, + 0x8093, 0xEBC1, + 0x8096, 0xD0A4, + 0x8098, 0xD6E2, + 0x809A, 0xB6C7, + 0x809B, 0xB8D8, + 0x809C, 0xEBC0, + 0x809D, 0xB8CE, + 0x809F, 0xEBBF, + 0x80A0, 0xB3A6, + 0x80A1, 0xB9C9, + 0x80A2, 0xD6AB, + 0x80A4, 0xB7F4, + 0x80A5, 0xB7CA, + 0x80A9, 0xBCE7, + 0x80AA, 0xB7BE, + 0x80AB, 0xEBC6, + 0x80AD, 0xEBC7, + 0x80AE, 0xB0B9, + 0x80AF, 0xBFCF, + 0x80B1, 0xEBC5, + 0x80B2, 0xD3FD, + 0x80B4, 0xEBC8, + 0x80B7, 0xEBC9, + 0x80BA, 0xB7CE, + 0x80BC, 0xEBC2, + 0x80BD, 0xEBC4, + 0x80BE, 0xC9F6, + 0x80BF, 0xD6D7, + 0x80C0, 0xD5CD, + 0x80C1, 0xD0B2, + 0x80C2, 0xEBCF, + 0x80C3, 0xCEB8, + 0x80C4, 0xEBD0, + 0x80C6, 0xB5A8, + 0x80CC, 0xB1B3, + 0x80CD, 0xEBD2, + 0x80CE, 0xCCA5, + 0x80D6, 0xC5D6, + 0x80D7, 0xEBD3, + 0x80D9, 0xEBD1, + 0x80DA, 0xC5DF, + 0x80DB, 0xEBCE, + 0x80DC, 0xCAA4, + 0x80DD, 0xEBD5, + 0x80DE, 0xB0FB, + 0x80E1, 0xBAFA, + 0x80E4, 0xD8B7, + 0x80E5, 0xF1E3, + 0x80E7, 0xEBCA, + 0x80E8, 0xEBCB, + 0x80E9, 0xEBCC, + 0x80EA, 0xEBCD, + 0x80EB, 0xEBD6, + 0x80EC, 0xE6C0, + 0x80ED, 0xEBD9, + 0x80EF, 0xBFE8, + 0x80F0, 0xD2C8, + 0x80F1, 0xEBD7, + 0x80F2, 0xEBDC, + 0x80F3, 0xB8EC, + 0x80F4, 0xEBD8, + 0x80F6, 0xBDBA, + 0x80F8, 0xD0D8, + 0x80FA, 0xB0B7, + 0x80FC, 0xEBDD, + 0x80FD, 0xC4DC, + 0x8102, 0xD6AC, + 0x8106, 0xB4E0, + 0x8109, 0xC2F6, + 0x810A, 0xBCB9, + 0x810D, 0xEBDA, + 0x810E, 0xEBDB, + 0x810F, 0xD4E0, + 0x8110, 0xC6EA, + 0x8111, 0xC4D4, + 0x8112, 0xEBDF, + 0x8113, 0xC5A7, + 0x8114, 0xD9F5, + 0x8116, 0xB2B1, + 0x8118, 0xEBE4, + 0x811A, 0xBDC5, + 0x811E, 0xEBE2, + 0x812C, 0xEBE3, + 0x812F, 0xB8AC, + 0x8131, 0xCDD1, + 0x8132, 0xEBE5, + 0x8136, 0xEBE1, + 0x8138, 0xC1B3, + 0x813E, 0xC6A2, + 0x8146, 0xCCF3, + 0x8148, 0xEBE6, + 0x814A, 0xC0B0, + 0x814B, 0xD2B8, + 0x814C, 0xEBE7, + 0x8150, 0xB8AF, + 0x8151, 0xB8AD, + 0x8153, 0xEBE8, + 0x8154, 0xC7BB, + 0x8155, 0xCDF3, + 0x8159, 0xEBEA, + 0x815A, 0xEBEB, + 0x8160, 0xEBED, + 0x8165, 0xD0C8, + 0x8167, 0xEBF2, + 0x8169, 0xEBEE, + 0x816D, 0xEBF1, + 0x816E, 0xC8F9, + 0x8170, 0xD1FC, + 0x8171, 0xEBEC, + 0x8174, 0xEBE9, + 0x8179, 0xB8B9, + 0x817A, 0xCFD9, + 0x817B, 0xC4E5, + 0x817C, 0xEBEF, + 0x817D, 0xEBF0, + 0x817E, 0xCCDA, + 0x817F, 0xCDC8, + 0x8180, 0xB0F2, + 0x8182, 0xEBF6, + 0x8188, 0xEBF5, + 0x818A, 0xB2B2, + 0x818F, 0xB8E0, + 0x8191, 0xEBF7, + 0x8198, 0xB1EC, + 0x819B, 0xCCC5, + 0x819C, 0xC4A4, + 0x819D, 0xCFA5, + 0x81A3, 0xEBF9, + 0x81A6, 0xECA2, + 0x81A8, 0xC5F2, + 0x81AA, 0xEBFA, + 0x81B3, 0xC9C5, + 0x81BA, 0xE2DF, + 0x81BB, 0xEBFE, + 0x81C0, 0xCDCE, + 0x81C1, 0xECA1, + 0x81C2, 0xB1DB, + 0x81C3, 0xD3B7, + 0x81C6, 0xD2DC, + 0x81CA, 0xEBFD, + 0x81CC, 0xEBFB, + 0x81E3, 0xB3BC, + 0x81E7, 0xEAB0, + 0x81EA, 0xD7D4, + 0x81EC, 0xF4AB, + 0x81ED, 0xB3F4, + 0x81F3, 0xD6C1, + 0x81F4, 0xD6C2, + 0x81FB, 0xD5E9, + 0x81FC, 0xBECA, + 0x81FE, 0xF4A7, + 0x8200, 0xD2A8, + 0x8201, 0xF4A8, + 0x8202, 0xF4A9, + 0x8204, 0xF4AA, + 0x8205, 0xBECB, + 0x8206, 0xD3DF, + 0x820C, 0xC9E0, + 0x820D, 0xC9E1, + 0x8210, 0xF3C2, + 0x8212, 0xCAE6, + 0x8214, 0xCCF2, + 0x821B, 0xE2B6, + 0x821C, 0xCBB4, + 0x821E, 0xCEE8, + 0x821F, 0xD6DB, + 0x8221, 0xF4AD, + 0x8222, 0xF4AE, + 0x8223, 0xF4AF, + 0x8228, 0xF4B2, + 0x822A, 0xBABD, + 0x822B, 0xF4B3, + 0x822C, 0xB0E3, + 0x822D, 0xF4B0, + 0x822F, 0xF4B1, + 0x8230, 0xBDA2, + 0x8231, 0xB2D5, + 0x8233, 0xF4B6, + 0x8234, 0xF4B7, + 0x8235, 0xB6E6, + 0x8236, 0xB2B0, + 0x8237, 0xCFCF, + 0x8238, 0xF4B4, + 0x8239, 0xB4AC, + 0x823B, 0xF4B5, + 0x823E, 0xF4B8, + 0x8244, 0xF4B9, + 0x8247, 0xCDA7, + 0x8249, 0xF4BA, + 0x824B, 0xF4BB, + 0x824F, 0xF4BC, + 0x8258, 0xCBD2, + 0x825A, 0xF4BD, + 0x825F, 0xF4BE, + 0x8268, 0xF4BF, + 0x826E, 0xF4DE, + 0x826F, 0xC1BC, + 0x8270, 0xBCE8, + 0x8272, 0xC9AB, + 0x8273, 0xD1DE, + 0x8274, 0xE5F5, + 0x8279, 0xDCB3, + 0x827A, 0xD2D5, + 0x827D, 0xDCB4, + 0x827E, 0xB0AC, + 0x827F, 0xDCB5, + 0x8282, 0xBDDA, + 0x8284, 0xDCB9, + 0x8288, 0xD8C2, + 0x828A, 0xDCB7, + 0x828B, 0xD3F3, + 0x828D, 0xC9D6, + 0x828E, 0xDCBA, + 0x828F, 0xDCB6, + 0x8291, 0xDCBB, + 0x8292, 0xC3A2, + 0x8297, 0xDCBC, + 0x8298, 0xDCC5, + 0x8299, 0xDCBD, + 0x829C, 0xCEDF, + 0x829D, 0xD6A5, + 0x829F, 0xDCCF, + 0x82A1, 0xDCCD, + 0x82A4, 0xDCD2, + 0x82A5, 0xBDE6, + 0x82A6, 0xC2AB, + 0x82A8, 0xDCB8, + 0x82A9, 0xDCCB, + 0x82AA, 0xDCCE, + 0x82AB, 0xDCBE, + 0x82AC, 0xB7D2, + 0x82AD, 0xB0C5, + 0x82AE, 0xDCC7, + 0x82AF, 0xD0BE, + 0x82B0, 0xDCC1, + 0x82B1, 0xBBA8, + 0x82B3, 0xB7BC, + 0x82B4, 0xDCCC, + 0x82B7, 0xDCC6, + 0x82B8, 0xDCBF, + 0x82B9, 0xC7DB, + 0x82BD, 0xD1BF, + 0x82BE, 0xDCC0, + 0x82C1, 0xDCCA, + 0x82C4, 0xDCD0, + 0x82C7, 0xCEAD, + 0x82C8, 0xDCC2, + 0x82CA, 0xDCC3, + 0x82CB, 0xDCC8, + 0x82CC, 0xDCC9, + 0x82CD, 0xB2D4, + 0x82CE, 0xDCD1, + 0x82CF, 0xCBD5, + 0x82D1, 0xD4B7, + 0x82D2, 0xDCDB, + 0x82D3, 0xDCDF, + 0x82D4, 0xCCA6, + 0x82D5, 0xDCE6, + 0x82D7, 0xC3E7, + 0x82D8, 0xDCDC, + 0x82DB, 0xBFC1, + 0x82DC, 0xDCD9, + 0x82DE, 0xB0FA, + 0x82DF, 0xB9B6, + 0x82E0, 0xDCE5, + 0x82E1, 0xDCD3, + 0x82E3, 0xDCC4, + 0x82E4, 0xDCD6, + 0x82E5, 0xC8F4, + 0x82E6, 0xBFE0, + 0x82EB, 0xC9BB, + 0x82EF, 0xB1BD, + 0x82F1, 0xD3A2, + 0x82F4, 0xDCDA, + 0x82F7, 0xDCD5, + 0x82F9, 0xC6BB, + 0x82FB, 0xDCDE, + 0x8301, 0xD7C2, + 0x8302, 0xC3AF, + 0x8303, 0xB7B6, + 0x8304, 0xC7D1, + 0x8305, 0xC3A9, + 0x8306, 0xDCE2, + 0x8307, 0xDCD8, + 0x8308, 0xDCEB, + 0x8309, 0xDCD4, + 0x830C, 0xDCDD, + 0x830E, 0xBEA5, + 0x830F, 0xDCD7, + 0x8311, 0xDCE0, + 0x8314, 0xDCE3, + 0x8315, 0xDCE4, + 0x8317, 0xDCF8, + 0x831A, 0xDCE1, + 0x831B, 0xDDA2, + 0x831C, 0xDCE7, + 0x8327, 0xBCEB, + 0x8328, 0xB4C4, + 0x832B, 0xC3A3, + 0x832C, 0xB2E7, + 0x832D, 0xDCFA, + 0x832F, 0xDCF2, + 0x8331, 0xDCEF, + 0x8333, 0xDCFC, + 0x8334, 0xDCEE, + 0x8335, 0xD2F0, + 0x8336, 0xB2E8, + 0x8338, 0xC8D7, + 0x8339, 0xC8E3, + 0x833A, 0xDCFB, + 0x833C, 0xDCED, + 0x8340, 0xDCF7, + 0x8343, 0xDCF5, + 0x8346, 0xBEA3, + 0x8347, 0xDCF4, + 0x8349, 0xB2DD, + 0x834F, 0xDCF3, + 0x8350, 0xBCF6, + 0x8351, 0xDCE8, + 0x8352, 0xBBC4, + 0x8354, 0xC0F3, + 0x835A, 0xBCD4, + 0x835B, 0xDCE9, + 0x835C, 0xDCEA, + 0x835E, 0xDCF1, + 0x835F, 0xDCF6, + 0x8360, 0xDCF9, + 0x8361, 0xB5B4, + 0x8363, 0xC8D9, + 0x8364, 0xBBE7, + 0x8365, 0xDCFE, + 0x8366, 0xDCFD, + 0x8367, 0xD3AB, + 0x8368, 0xDDA1, + 0x8369, 0xDDA3, + 0x836A, 0xDDA5, + 0x836B, 0xD2F1, + 0x836C, 0xDDA4, + 0x836D, 0xDDA6, + 0x836E, 0xDDA7, + 0x836F, 0xD2A9, + 0x8377, 0xBAC9, + 0x8378, 0xDDA9, + 0x837B, 0xDDB6, + 0x837C, 0xDDB1, + 0x837D, 0xDDB4, + 0x8385, 0xDDB0, + 0x8386, 0xC6CE, + 0x8389, 0xC0F2, + 0x838E, 0xC9AF, + 0x8392, 0xDCEC, + 0x8393, 0xDDAE, + 0x8398, 0xDDB7, + 0x839B, 0xDCF0, + 0x839C, 0xDDAF, + 0x839E, 0xDDB8, + 0x83A0, 0xDDAC, + 0x83A8, 0xDDB9, + 0x83A9, 0xDDB3, + 0x83AA, 0xDDAD, + 0x83AB, 0xC4AA, + 0x83B0, 0xDDA8, + 0x83B1, 0xC0B3, + 0x83B2, 0xC1AB, + 0x83B3, 0xDDAA, + 0x83B4, 0xDDAB, + 0x83B6, 0xDDB2, + 0x83B7, 0xBBF1, + 0x83B8, 0xDDB5, + 0x83B9, 0xD3A8, + 0x83BA, 0xDDBA, + 0x83BC, 0xDDBB, + 0x83BD, 0xC3A7, + 0x83C0, 0xDDD2, + 0x83C1, 0xDDBC, + 0x83C5, 0xDDD1, + 0x83C7, 0xB9BD, + 0x83CA, 0xBED5, + 0x83CC, 0xBEFA, + 0x83CF, 0xBACA, + 0x83D4, 0xDDCA, + 0x83D6, 0xDDC5, + 0x83D8, 0xDDBF, + 0x83DC, 0xB2CB, + 0x83DD, 0xDDC3, + 0x83DF, 0xDDCB, + 0x83E0, 0xB2A4, + 0x83E1, 0xDDD5, + 0x83E5, 0xDDBE, + 0x83E9, 0xC6D0, + 0x83EA, 0xDDD0, + 0x83F0, 0xDDD4, + 0x83F1, 0xC1E2, + 0x83F2, 0xB7C6, + 0x83F8, 0xDDCE, + 0x83F9, 0xDDCF, + 0x83FD, 0xDDC4, + 0x8401, 0xDDBD, + 0x8403, 0xDDCD, + 0x8404, 0xCCD1, + 0x8406, 0xDDC9, + 0x840B, 0xDDC2, + 0x840C, 0xC3C8, + 0x840D, 0xC6BC, + 0x840E, 0xCEAE, + 0x840F, 0xDDCC, + 0x8411, 0xDDC8, + 0x8418, 0xDDC1, + 0x841C, 0xDDC6, + 0x841D, 0xC2DC, + 0x8424, 0xD3A9, + 0x8425, 0xD3AA, + 0x8426, 0xDDD3, + 0x8427, 0xCFF4, + 0x8428, 0xC8F8, + 0x8431, 0xDDE6, + 0x8438, 0xDDC7, + 0x843C, 0xDDE0, + 0x843D, 0xC2E4, + 0x8446, 0xDDE1, + 0x8451, 0xDDD7, + 0x8457, 0xD6F8, + 0x8459, 0xDDD9, + 0x845A, 0xDDD8, + 0x845B, 0xB8F0, + 0x845C, 0xDDD6, + 0x8461, 0xC6CF, + 0x8463, 0xB6AD, + 0x8469, 0xDDE2, + 0x846B, 0xBAF9, + 0x846C, 0xD4E1, + 0x846D, 0xDDE7, + 0x8471, 0xB4D0, + 0x8473, 0xDDDA, + 0x8475, 0xBFFB, + 0x8476, 0xDDE3, + 0x8478, 0xDDDF, + 0x847A, 0xDDDD, + 0x8482, 0xB5D9, + 0x8487, 0xDDDB, + 0x8488, 0xDDDC, + 0x8489, 0xDDDE, + 0x848B, 0xBDAF, + 0x848C, 0xDDE4, + 0x848E, 0xDDE5, + 0x8497, 0xDDF5, + 0x8499, 0xC3C9, + 0x849C, 0xCBE2, + 0x84A1, 0xDDF2, + 0x84AF, 0xD8E1, + 0x84B2, 0xC6D1, + 0x84B4, 0xDDF4, + 0x84B8, 0xD5F4, + 0x84B9, 0xDDF3, + 0x84BA, 0xDDF0, + 0x84BD, 0xDDEC, + 0x84BF, 0xDDEF, + 0x84C1, 0xDDE8, + 0x84C4, 0xD0EE, + 0x84C9, 0xC8D8, + 0x84CA, 0xDDEE, + 0x84CD, 0xDDE9, + 0x84D0, 0xDDEA, + 0x84D1, 0xCBF2, + 0x84D3, 0xDDED, + 0x84D6, 0xB1CD, + 0x84DD, 0xC0B6, + 0x84DF, 0xBCBB, + 0x84E0, 0xDDF1, + 0x84E3, 0xDDF7, + 0x84E5, 0xDDF6, + 0x84E6, 0xDDEB, + 0x84EC, 0xC5EE, + 0x84F0, 0xDDFB, + 0x84FC, 0xDEA4, + 0x84FF, 0xDEA3, + 0x850C, 0xDDF8, + 0x8511, 0xC3EF, + 0x8513, 0xC2FB, + 0x8517, 0xD5E1, + 0x851A, 0xCEB5, + 0x851F, 0xDDFD, + 0x8521, 0xB2CC, + 0x852B, 0xC4E8, + 0x852C, 0xCADF, + 0x8537, 0xC7BE, + 0x8538, 0xDDFA, + 0x8539, 0xDDFC, + 0x853A, 0xDDFE, + 0x853B, 0xDEA2, + 0x853C, 0xB0AA, + 0x853D, 0xB1CE, + 0x8543, 0xDEAC, + 0x8548, 0xDEA6, + 0x8549, 0xBDB6, + 0x854A, 0xC8EF, + 0x8556, 0xDEA1, + 0x8559, 0xDEA5, + 0x855E, 0xDEA9, + 0x8564, 0xDEA8, + 0x8568, 0xDEA7, + 0x8572, 0xDEAD, + 0x8574, 0xD4CC, + 0x8579, 0xDEB3, + 0x857A, 0xDEAA, + 0x857B, 0xDEAE, + 0x857E, 0xC0D9, + 0x8584, 0xB1A1, + 0x8585, 0xDEB6, + 0x8587, 0xDEB1, + 0x858F, 0xDEB2, + 0x859B, 0xD1A6, + 0x859C, 0xDEB5, + 0x85A4, 0xDEAF, + 0x85A8, 0xDEB0, + 0x85AA, 0xD0BD, + 0x85AE, 0xDEB4, + 0x85AF, 0xCAED, + 0x85B0, 0xDEB9, + 0x85B7, 0xDEB8, + 0x85B9, 0xDEB7, + 0x85C1, 0xDEBB, + 0x85C9, 0xBDE5, + 0x85CF, 0xB2D8, + 0x85D0, 0xC3EA, + 0x85D3, 0xDEBA, + 0x85D5, 0xC5BA, + 0x85DC, 0xDEBC, + 0x85E4, 0xCCD9, + 0x85E9, 0xB7AA, + 0x85FB, 0xD4E5, + 0x85FF, 0xDEBD, + 0x8605, 0xDEBF, + 0x8611, 0xC4A2, + 0x8616, 0xDEC1, + 0x8627, 0xDEBE, + 0x8629, 0xDEC0, + 0x8638, 0xD5BA, + 0x863C, 0xDEC2, + 0x864D, 0xF2AE, + 0x864E, 0xBBA2, + 0x864F, 0xC2B2, + 0x8650, 0xC5B0, + 0x8651, 0xC2C7, + 0x8654, 0xF2AF, + 0x865A, 0xD0E9, + 0x865E, 0xD3DD, + 0x8662, 0xEBBD, + 0x866B, 0xB3E6, + 0x866C, 0xF2B0, + 0x866E, 0xF2B1, + 0x8671, 0xCAAD, + 0x8679, 0xBAE7, + 0x867A, 0xF2B3, + 0x867B, 0xF2B5, + 0x867C, 0xF2B4, + 0x867D, 0xCBE4, + 0x867E, 0xCFBA, + 0x867F, 0xF2B2, + 0x8680, 0xCAB4, + 0x8681, 0xD2CF, + 0x8682, 0xC2EC, + 0x868A, 0xCEC3, + 0x868B, 0xF2B8, + 0x868C, 0xB0F6, + 0x868D, 0xF2B7, + 0x8693, 0xF2BE, + 0x8695, 0xB2CF, + 0x869C, 0xD1C1, + 0x869D, 0xF2BA, + 0x86A3, 0xF2BC, + 0x86A4, 0xD4E9, + 0x86A7, 0xF2BB, + 0x86A8, 0xF2B6, + 0x86A9, 0xF2BF, + 0x86AA, 0xF2BD, + 0x86AC, 0xF2B9, + 0x86AF, 0xF2C7, + 0x86B0, 0xF2C4, + 0x86B1, 0xF2C6, + 0x86B4, 0xF2CA, + 0x86B5, 0xF2C2, + 0x86B6, 0xF2C0, + 0x86BA, 0xF2C5, + 0x86C0, 0xD6FB, + 0x86C4, 0xF2C1, + 0x86C6, 0xC7F9, + 0x86C7, 0xC9DF, + 0x86C9, 0xF2C8, + 0x86CA, 0xB9C6, + 0x86CB, 0xB5B0, + 0x86CE, 0xF2C3, + 0x86CF, 0xF2C9, + 0x86D0, 0xF2D0, + 0x86D1, 0xF2D6, + 0x86D4, 0xBBD7, + 0x86D8, 0xF2D5, + 0x86D9, 0xCDDC, + 0x86DB, 0xD6EB, + 0x86DE, 0xF2D2, + 0x86DF, 0xF2D4, + 0x86E4, 0xB8F2, + 0x86E9, 0xF2CB, + 0x86ED, 0xF2CE, + 0x86EE, 0xC2F9, + 0x86F0, 0xD5DD, + 0x86F1, 0xF2CC, + 0x86F2, 0xF2CD, + 0x86F3, 0xF2CF, + 0x86F4, 0xF2D3, + 0x86F8, 0xF2D9, + 0x86F9, 0xD3BC, + 0x86FE, 0xB6EA, + 0x8700, 0xCAF1, + 0x8702, 0xB7E4, + 0x8703, 0xF2D7, + 0x8707, 0xF2D8, + 0x8708, 0xF2DA, + 0x8709, 0xF2DD, + 0x870A, 0xF2DB, + 0x870D, 0xF2DC, + 0x8712, 0xD1D1, + 0x8713, 0xF2D1, + 0x8715, 0xCDC9, + 0x8717, 0xCECF, + 0x8718, 0xD6A9, + 0x871A, 0xF2E3, + 0x871C, 0xC3DB, + 0x871E, 0xF2E0, + 0x8721, 0xC0AF, + 0x8722, 0xF2EC, + 0x8723, 0xF2DE, + 0x8725, 0xF2E1, + 0x8729, 0xF2E8, + 0x872E, 0xF2E2, + 0x8731, 0xF2E7, + 0x8734, 0xF2E6, + 0x8737, 0xF2E9, + 0x873B, 0xF2DF, + 0x873E, 0xF2E4, + 0x873F, 0xF2EA, + 0x8747, 0xD3AC, + 0x8748, 0xF2E5, + 0x8749, 0xB2F5, + 0x874C, 0xF2F2, + 0x874E, 0xD0AB, + 0x8753, 0xF2F5, + 0x8757, 0xBBC8, + 0x8759, 0xF2F9, + 0x8760, 0xF2F0, + 0x8763, 0xF2F6, + 0x8764, 0xF2F8, + 0x8765, 0xF2FA, + 0x876E, 0xF2F3, + 0x8770, 0xF2F1, + 0x8774, 0xBAFB, + 0x8776, 0xB5FB, + 0x877B, 0xF2EF, + 0x877C, 0xF2F7, + 0x877D, 0xF2ED, + 0x877E, 0xF2EE, + 0x8782, 0xF2EB, + 0x8783, 0xF3A6, + 0x8785, 0xF3A3, + 0x8788, 0xF3A2, + 0x878B, 0xF2F4, + 0x878D, 0xC8DA, + 0x8793, 0xF2FB, + 0x8797, 0xF3A5, + 0x879F, 0xC3F8, + 0x87A8, 0xF2FD, + 0x87AB, 0xF3A7, + 0x87AC, 0xF3A9, + 0x87AD, 0xF3A4, + 0x87AF, 0xF2FC, + 0x87B3, 0xF3AB, + 0x87B5, 0xF3AA, + 0x87BA, 0xC2DD, + 0x87BD, 0xF3AE, + 0x87C0, 0xF3B0, + 0x87C6, 0xF3A1, + 0x87CA, 0xF3B1, + 0x87CB, 0xF3AC, + 0x87D1, 0xF3AF, + 0x87D2, 0xF2FE, + 0x87D3, 0xF3AD, + 0x87DB, 0xF3B2, + 0x87E0, 0xF3B4, + 0x87E5, 0xF3A8, + 0x87EA, 0xF3B3, + 0x87EE, 0xF3B5, + 0x87F9, 0xD0B7, + 0x87FE, 0xF3B8, + 0x8803, 0xD9F9, + 0x880A, 0xF3B9, + 0x8813, 0xF3B7, + 0x8815, 0xC8E4, + 0x8816, 0xF3B6, + 0x881B, 0xF3BA, + 0x8821, 0xF3BB, + 0x8822, 0xB4C0, + 0x8832, 0xEEC3, + 0x8839, 0xF3BC, + 0x883C, 0xF3BD, + 0x8840, 0xD1AA, + 0x8844, 0xF4AC, + 0x8845, 0xD0C6, + 0x884C, 0xD0D0, + 0x884D, 0xD1DC, + 0x8854, 0xCFCE, + 0x8857, 0xBDD6, + 0x8859, 0xD1C3, + 0x8861, 0xBAE2, + 0x8862, 0xE1E9, + 0x8863, 0xD2C2, + 0x8864, 0xF1C2, + 0x8865, 0xB2B9, + 0x8868, 0xB1ED, + 0x8869, 0xF1C3, + 0x886B, 0xC9C0, + 0x886C, 0xB3C4, + 0x886E, 0xD9F2, + 0x8870, 0xCBA5, + 0x8872, 0xF1C4, + 0x8877, 0xD6D4, + 0x887D, 0xF1C5, + 0x887E, 0xF4C0, + 0x887F, 0xF1C6, + 0x8881, 0xD4AC, + 0x8882, 0xF1C7, + 0x8884, 0xB0C0, + 0x8885, 0xF4C1, + 0x8888, 0xF4C2, + 0x888B, 0xB4FC, + 0x888D, 0xC5DB, + 0x8892, 0xCCBB, + 0x8896, 0xD0E4, + 0x889C, 0xCDE0, + 0x88A2, 0xF1C8, + 0x88A4, 0xD9F3, + 0x88AB, 0xB1BB, + 0x88AD, 0xCFAE, + 0x88B1, 0xB8A4, + 0x88B7, 0xF1CA, + 0x88BC, 0xF1CB, + 0x88C1, 0xB2C3, + 0x88C2, 0xC1D1, + 0x88C5, 0xD7B0, + 0x88C6, 0xF1C9, + 0x88C9, 0xF1CC, + 0x88CE, 0xF1CE, + 0x88D2, 0xD9F6, + 0x88D4, 0xD2E1, + 0x88D5, 0xD4A3, + 0x88D8, 0xF4C3, + 0x88D9, 0xC8B9, + 0x88DF, 0xF4C4, + 0x88E2, 0xF1CD, + 0x88E3, 0xF1CF, + 0x88E4, 0xBFE3, + 0x88E5, 0xF1D0, + 0x88E8, 0xF1D4, + 0x88F0, 0xF1D6, + 0x88F1, 0xF1D1, + 0x88F3, 0xC9D1, + 0x88F4, 0xC5E1, + 0x88F8, 0xC2E3, + 0x88F9, 0xB9FC, + 0x88FC, 0xF1D3, + 0x88FE, 0xF1D5, + 0x8902, 0xB9D3, + 0x890A, 0xF1DB, + 0x8910, 0xBAD6, + 0x8912, 0xB0FD, + 0x8913, 0xF1D9, + 0x8919, 0xF1D8, + 0x891A, 0xF1D2, + 0x891B, 0xF1DA, + 0x8921, 0xF1D7, + 0x8925, 0xC8EC, + 0x892A, 0xCDCA, + 0x892B, 0xF1DD, + 0x8930, 0xE5BD, + 0x8934, 0xF1DC, + 0x8936, 0xF1DE, + 0x8941, 0xF1DF, + 0x8944, 0xCFE5, + 0x895E, 0xF4C5, + 0x895F, 0xBDF3, + 0x8966, 0xF1E0, + 0x897B, 0xF1E1, + 0x897F, 0xCEF7, + 0x8981, 0xD2AA, + 0x8983, 0xF1FB, + 0x8986, 0xB8B2, + 0x89C1, 0xBCFB, + 0x89C2, 0xB9DB, + 0x89C4, 0xB9E6, + 0x89C5, 0xC3D9, + 0x89C6, 0xCAD3, + 0x89C7, 0xEAE8, + 0x89C8, 0xC0C0, + 0x89C9, 0xBEF5, + 0x89CA, 0xEAE9, + 0x89CB, 0xEAEA, + 0x89CC, 0xEAEB, + 0x89CE, 0xEAEC, + 0x89CF, 0xEAED, + 0x89D0, 0xEAEE, + 0x89D1, 0xEAEF, + 0x89D2, 0xBDC7, + 0x89D6, 0xF5FB, + 0x89DA, 0xF5FD, + 0x89DC, 0xF5FE, + 0x89DE, 0xF5FC, + 0x89E3, 0xBDE2, + 0x89E5, 0xF6A1, + 0x89E6, 0xB4A5, + 0x89EB, 0xF6A2, + 0x89EF, 0xF6A3, + 0x89F3, 0xECB2, + 0x8A00, 0xD1D4, + 0x8A07, 0xD9EA, + 0x8A3E, 0xF6A4, + 0x8A48, 0xEEBA, + 0x8A79, 0xD5B2, + 0x8A89, 0xD3FE, + 0x8A8A, 0xCCDC, + 0x8A93, 0xCAC4, + 0x8B07, 0xE5C0, + 0x8B26, 0xF6A5, + 0x8B66, 0xBEAF, + 0x8B6C, 0xC6A9, + 0x8BA0, 0xDAA5, + 0x8BA1, 0xBCC6, + 0x8BA2, 0xB6A9, + 0x8BA3, 0xB8BC, + 0x8BA4, 0xC8CF, + 0x8BA5, 0xBCA5, + 0x8BA6, 0xDAA6, + 0x8BA7, 0xDAA7, + 0x8BA8, 0xCCD6, + 0x8BA9, 0xC8C3, + 0x8BAA, 0xDAA8, + 0x8BAB, 0xC6FD, + 0x8BAD, 0xD1B5, + 0x8BAE, 0xD2E9, + 0x8BAF, 0xD1B6, + 0x8BB0, 0xBCC7, + 0x8BB2, 0xBDB2, + 0x8BB3, 0xBBE4, + 0x8BB4, 0xDAA9, + 0x8BB5, 0xDAAA, + 0x8BB6, 0xD1C8, + 0x8BB7, 0xDAAB, + 0x8BB8, 0xD0ED, + 0x8BB9, 0xB6EF, + 0x8BBA, 0xC2DB, + 0x8BBC, 0xCBCF, + 0x8BBD, 0xB7ED, + 0x8BBE, 0xC9E8, + 0x8BBF, 0xB7C3, + 0x8BC0, 0xBEF7, + 0x8BC1, 0xD6A4, + 0x8BC2, 0xDAAC, + 0x8BC3, 0xDAAD, + 0x8BC4, 0xC6C0, + 0x8BC5, 0xD7E7, + 0x8BC6, 0xCAB6, + 0x8BC8, 0xD5A9, + 0x8BC9, 0xCBDF, + 0x8BCA, 0xD5EF, + 0x8BCB, 0xDAAE, + 0x8BCC, 0xD6DF, + 0x8BCD, 0xB4CA, + 0x8BCE, 0xDAB0, + 0x8BCF, 0xDAAF, + 0x8BD1, 0xD2EB, + 0x8BD2, 0xDAB1, + 0x8BD3, 0xDAB2, + 0x8BD4, 0xDAB3, + 0x8BD5, 0xCAD4, + 0x8BD6, 0xDAB4, + 0x8BD7, 0xCAAB, + 0x8BD8, 0xDAB5, + 0x8BD9, 0xDAB6, + 0x8BDA, 0xB3CF, + 0x8BDB, 0xD6EF, + 0x8BDC, 0xDAB7, + 0x8BDD, 0xBBB0, + 0x8BDE, 0xB5AE, + 0x8BDF, 0xDAB8, + 0x8BE0, 0xDAB9, + 0x8BE1, 0xB9EE, + 0x8BE2, 0xD1AF, + 0x8BE3, 0xD2E8, + 0x8BE4, 0xDABA, + 0x8BE5, 0xB8C3, + 0x8BE6, 0xCFEA, + 0x8BE7, 0xB2EF, + 0x8BE8, 0xDABB, + 0x8BE9, 0xDABC, + 0x8BEB, 0xBDEB, + 0x8BEC, 0xCEDC, + 0x8BED, 0xD3EF, + 0x8BEE, 0xDABD, + 0x8BEF, 0xCEF3, + 0x8BF0, 0xDABE, + 0x8BF1, 0xD3D5, + 0x8BF2, 0xBBE5, + 0x8BF3, 0xDABF, + 0x8BF4, 0xCBB5, + 0x8BF5, 0xCBD0, + 0x8BF6, 0xDAC0, + 0x8BF7, 0xC7EB, + 0x8BF8, 0xD6EE, + 0x8BF9, 0xDAC1, + 0x8BFA, 0xC5B5, + 0x8BFB, 0xB6C1, + 0x8BFC, 0xDAC2, + 0x8BFD, 0xB7CC, + 0x8BFE, 0xBFCE, + 0x8BFF, 0xDAC3, + 0x8C00, 0xDAC4, + 0x8C01, 0xCBAD, + 0x8C02, 0xDAC5, + 0x8C03, 0xB5F7, + 0x8C04, 0xDAC6, + 0x8C05, 0xC1C2, + 0x8C06, 0xD7BB, + 0x8C07, 0xDAC7, + 0x8C08, 0xCCB8, + 0x8C0A, 0xD2EA, + 0x8C0B, 0xC4B1, + 0x8C0C, 0xDAC8, + 0x8C0D, 0xB5FD, + 0x8C0E, 0xBBD1, + 0x8C0F, 0xDAC9, + 0x8C10, 0xD0B3, + 0x8C11, 0xDACA, + 0x8C12, 0xDACB, + 0x8C13, 0xCEBD, + 0x8C14, 0xDACC, + 0x8C15, 0xDACD, + 0x8C16, 0xDACE, + 0x8C17, 0xB2F7, + 0x8C18, 0xDAD1, + 0x8C19, 0xDACF, + 0x8C1A, 0xD1E8, + 0x8C1B, 0xDAD0, + 0x8C1C, 0xC3D5, + 0x8C1D, 0xDAD2, + 0x8C1F, 0xDAD3, + 0x8C20, 0xDAD4, + 0x8C21, 0xDAD5, + 0x8C22, 0xD0BB, + 0x8C23, 0xD2A5, + 0x8C24, 0xB0F9, + 0x8C25, 0xDAD6, + 0x8C26, 0xC7AB, + 0x8C27, 0xDAD7, + 0x8C28, 0xBDF7, + 0x8C29, 0xC3A1, + 0x8C2A, 0xDAD8, + 0x8C2B, 0xDAD9, + 0x8C2C, 0xC3FD, + 0x8C2D, 0xCCB7, + 0x8C2E, 0xDADA, + 0x8C2F, 0xDADB, + 0x8C30, 0xC0BE, + 0x8C31, 0xC6D7, + 0x8C32, 0xDADC, + 0x8C33, 0xDADD, + 0x8C34, 0xC7B4, + 0x8C35, 0xDADE, + 0x8C36, 0xDADF, + 0x8C37, 0xB9C8, + 0x8C41, 0xBBED, + 0x8C46, 0xB6B9, + 0x8C47, 0xF4F8, + 0x8C49, 0xF4F9, + 0x8C4C, 0xCDE3, + 0x8C55, 0xF5B9, + 0x8C5A, 0xEBE0, + 0x8C61, 0xCFF3, + 0x8C62, 0xBBBF, + 0x8C6A, 0xBAC0, + 0x8C6B, 0xD4A5, + 0x8C73, 0xE1D9, + 0x8C78, 0xF5F4, + 0x8C79, 0xB1AA, + 0x8C7A, 0xB2F2, + 0x8C82, 0xF5F5, + 0x8C85, 0xF5F7, + 0x8C89, 0xBAD1, + 0x8C8A, 0xF5F6, + 0x8C8C, 0xC3B2, + 0x8C94, 0xF5F9, + 0x8C98, 0xF5F8, + 0x8D1D, 0xB1B4, + 0x8D1E, 0xD5EA, + 0x8D1F, 0xB8BA, + 0x8D21, 0xB9B1, + 0x8D22, 0xB2C6, + 0x8D23, 0xD4F0, + 0x8D24, 0xCFCD, + 0x8D25, 0xB0DC, + 0x8D26, 0xD5CB, + 0x8D27, 0xBBF5, + 0x8D28, 0xD6CA, + 0x8D29, 0xB7B7, + 0x8D2A, 0xCCB0, + 0x8D2B, 0xC6B6, + 0x8D2C, 0xB1E1, + 0x8D2D, 0xB9BA, + 0x8D2E, 0xD6FC, + 0x8D2F, 0xB9E1, + 0x8D30, 0xB7A1, + 0x8D31, 0xBCFA, + 0x8D32, 0xEADA, + 0x8D33, 0xEADB, + 0x8D34, 0xCCF9, + 0x8D35, 0xB9F3, + 0x8D36, 0xEADC, + 0x8D37, 0xB4FB, + 0x8D38, 0xC3B3, + 0x8D39, 0xB7D1, + 0x8D3A, 0xBAD8, + 0x8D3B, 0xEADD, + 0x8D3C, 0xD4F4, + 0x8D3D, 0xEADE, + 0x8D3E, 0xBCD6, + 0x8D3F, 0xBBDF, + 0x8D40, 0xEADF, + 0x8D41, 0xC1DE, + 0x8D42, 0xC2B8, + 0x8D43, 0xD4DF, + 0x8D44, 0xD7CA, + 0x8D45, 0xEAE0, + 0x8D46, 0xEAE1, + 0x8D47, 0xEAE4, + 0x8D48, 0xEAE2, + 0x8D49, 0xEAE3, + 0x8D4A, 0xC9DE, + 0x8D4B, 0xB8B3, + 0x8D4C, 0xB6C4, + 0x8D4D, 0xEAE5, + 0x8D4E, 0xCAEA, + 0x8D4F, 0xC9CD, + 0x8D50, 0xB4CD, + 0x8D53, 0xE2D9, + 0x8D54, 0xC5E2, + 0x8D55, 0xEAE6, + 0x8D56, 0xC0B5, + 0x8D58, 0xD7B8, + 0x8D59, 0xEAE7, + 0x8D5A, 0xD7AC, + 0x8D5B, 0xC8FC, + 0x8D5C, 0xD8D3, + 0x8D5D, 0xD8CD, + 0x8D5E, 0xD4DE, + 0x8D60, 0xD4F9, + 0x8D61, 0xC9C4, + 0x8D62, 0xD3AE, + 0x8D63, 0xB8D3, + 0x8D64, 0xB3E0, + 0x8D66, 0xC9E2, + 0x8D67, 0xF4F6, + 0x8D6B, 0xBAD5, + 0x8D6D, 0xF4F7, + 0x8D70, 0xD7DF, + 0x8D73, 0xF4F1, + 0x8D74, 0xB8B0, + 0x8D75, 0xD5D4, + 0x8D76, 0xB8CF, + 0x8D77, 0xC6F0, + 0x8D81, 0xB3C3, + 0x8D84, 0xF4F2, + 0x8D85, 0xB3AC, + 0x8D8A, 0xD4BD, + 0x8D8B, 0xC7F7, + 0x8D91, 0xF4F4, + 0x8D94, 0xF4F3, + 0x8D9F, 0xCCCB, + 0x8DA3, 0xC8A4, + 0x8DB1, 0xF4F5, + 0x8DB3, 0xD7E3, + 0x8DB4, 0xC5BF, + 0x8DB5, 0xF5C0, + 0x8DB8, 0xF5BB, + 0x8DBA, 0xF5C3, + 0x8DBC, 0xF5C2, + 0x8DBE, 0xD6BA, + 0x8DBF, 0xF5C1, + 0x8DC3, 0xD4BE, + 0x8DC4, 0xF5C4, + 0x8DC6, 0xF5CC, + 0x8DCB, 0xB0CF, + 0x8DCC, 0xB5F8, + 0x8DCE, 0xF5C9, + 0x8DCF, 0xF5CA, + 0x8DD1, 0xC5DC, + 0x8DD6, 0xF5C5, + 0x8DD7, 0xF5C6, + 0x8DDA, 0xF5C7, + 0x8DDB, 0xF5CB, + 0x8DDD, 0xBEE0, + 0x8DDE, 0xF5C8, + 0x8DDF, 0xB8FA, + 0x8DE3, 0xF5D0, + 0x8DE4, 0xF5D3, + 0x8DE8, 0xBFE7, + 0x8DEA, 0xB9F2, + 0x8DEB, 0xF5BC, + 0x8DEC, 0xF5CD, + 0x8DEF, 0xC2B7, + 0x8DF3, 0xCCF8, + 0x8DF5, 0xBCF9, + 0x8DF7, 0xF5CE, + 0x8DF8, 0xF5CF, + 0x8DF9, 0xF5D1, + 0x8DFA, 0xB6E5, + 0x8DFB, 0xF5D2, + 0x8DFD, 0xF5D5, + 0x8E05, 0xF5BD, + 0x8E09, 0xF5D4, + 0x8E0A, 0xD3BB, + 0x8E0C, 0xB3EC, + 0x8E0F, 0xCCA4, + 0x8E14, 0xF5D6, + 0x8E1D, 0xF5D7, + 0x8E1E, 0xBEE1, + 0x8E1F, 0xF5D8, + 0x8E22, 0xCCDF, + 0x8E23, 0xF5DB, + 0x8E29, 0xB2C8, + 0x8E2A, 0xD7D9, + 0x8E2C, 0xF5D9, + 0x8E2E, 0xF5DA, + 0x8E2F, 0xF5DC, + 0x8E31, 0xF5E2, + 0x8E35, 0xF5E0, + 0x8E39, 0xF5DF, + 0x8E3A, 0xF5DD, + 0x8E3D, 0xF5E1, + 0x8E40, 0xF5DE, + 0x8E41, 0xF5E4, + 0x8E42, 0xF5E5, + 0x8E44, 0xCCE3, + 0x8E47, 0xE5BF, + 0x8E48, 0xB5B8, + 0x8E49, 0xF5E3, + 0x8E4A, 0xF5E8, + 0x8E4B, 0xCCA3, + 0x8E51, 0xF5E6, + 0x8E52, 0xF5E7, + 0x8E59, 0xF5BE, + 0x8E66, 0xB1C4, + 0x8E69, 0xF5BF, + 0x8E6C, 0xB5C5, + 0x8E6D, 0xB2E4, + 0x8E6F, 0xF5EC, + 0x8E70, 0xF5E9, + 0x8E72, 0xB6D7, + 0x8E74, 0xF5ED, + 0x8E76, 0xF5EA, + 0x8E7C, 0xF5EB, + 0x8E7F, 0xB4DA, + 0x8E81, 0xD4EA, + 0x8E85, 0xF5EE, + 0x8E87, 0xB3F9, + 0x8E8F, 0xF5EF, + 0x8E90, 0xF5F1, + 0x8E94, 0xF5F0, + 0x8E9C, 0xF5F2, + 0x8E9E, 0xF5F3, + 0x8EAB, 0xC9ED, + 0x8EAC, 0xB9AA, + 0x8EAF, 0xC7FB, + 0x8EB2, 0xB6E3, + 0x8EBA, 0xCCC9, + 0x8ECE, 0xEAA6, + 0x8F66, 0xB3B5, + 0x8F67, 0xD4FE, + 0x8F68, 0xB9EC, + 0x8F69, 0xD0F9, + 0x8F6B, 0xE9ED, + 0x8F6C, 0xD7AA, + 0x8F6D, 0xE9EE, + 0x8F6E, 0xC2D6, + 0x8F6F, 0xC8ED, + 0x8F70, 0xBAE4, + 0x8F71, 0xE9EF, + 0x8F72, 0xE9F0, + 0x8F73, 0xE9F1, + 0x8F74, 0xD6E1, + 0x8F75, 0xE9F2, + 0x8F76, 0xE9F3, + 0x8F77, 0xE9F5, + 0x8F78, 0xE9F4, + 0x8F79, 0xE9F6, + 0x8F7A, 0xE9F7, + 0x8F7B, 0xC7E1, + 0x8F7C, 0xE9F8, + 0x8F7D, 0xD4D8, + 0x8F7E, 0xE9F9, + 0x8F7F, 0xBDCE, + 0x8F81, 0xE9FA, + 0x8F82, 0xE9FB, + 0x8F83, 0xBDCF, + 0x8F84, 0xE9FC, + 0x8F85, 0xB8A8, + 0x8F86, 0xC1BE, + 0x8F87, 0xE9FD, + 0x8F88, 0xB1B2, + 0x8F89, 0xBBD4, + 0x8F8A, 0xB9F5, + 0x8F8B, 0xE9FE, + 0x8F8D, 0xEAA1, + 0x8F8E, 0xEAA2, + 0x8F8F, 0xEAA3, + 0x8F90, 0xB7F8, + 0x8F91, 0xBCAD, + 0x8F93, 0xCAE4, + 0x8F94, 0xE0CE, + 0x8F95, 0xD4AF, + 0x8F96, 0xCFBD, + 0x8F97, 0xD5B7, + 0x8F98, 0xEAA4, + 0x8F99, 0xD5DE, + 0x8F9A, 0xEAA5, + 0x8F9B, 0xD0C1, + 0x8F9C, 0xB9BC, + 0x8F9E, 0xB4C7, + 0x8F9F, 0xB1D9, + 0x8FA3, 0xC0B1, + 0x8FA8, 0xB1E6, + 0x8FA9, 0xB1E7, + 0x8FAB, 0xB1E8, + 0x8FB0, 0xB3BD, + 0x8FB1, 0xC8E8, + 0x8FB6, 0xE5C1, + 0x8FB9, 0xB1DF, + 0x8FBD, 0xC1C9, + 0x8FBE, 0xB4EF, + 0x8FC1, 0xC7A8, + 0x8FC2, 0xD3D8, + 0x8FC4, 0xC6F9, + 0x8FC5, 0xD1B8, + 0x8FC7, 0xB9FD, + 0x8FC8, 0xC2F5, + 0x8FCE, 0xD3AD, + 0x8FD0, 0xD4CB, + 0x8FD1, 0xBDFC, + 0x8FD3, 0xE5C2, + 0x8FD4, 0xB7B5, + 0x8FD5, 0xE5C3, + 0x8FD8, 0xBBB9, + 0x8FD9, 0xD5E2, + 0x8FDB, 0xBDF8, + 0x8FDC, 0xD4B6, + 0x8FDD, 0xCEA5, + 0x8FDE, 0xC1AC, + 0x8FDF, 0xB3D9, + 0x8FE2, 0xCCF6, + 0x8FE4, 0xE5C6, + 0x8FE5, 0xE5C4, + 0x8FE6, 0xE5C8, + 0x8FE8, 0xE5CA, + 0x8FE9, 0xE5C7, + 0x8FEA, 0xB5CF, + 0x8FEB, 0xC6C8, + 0x8FED, 0xB5FC, + 0x8FEE, 0xE5C5, + 0x8FF0, 0xCAF6, + 0x8FF3, 0xE5C9, + 0x8FF7, 0xC3D4, + 0x8FF8, 0xB1C5, + 0x8FF9, 0xBCA3, + 0x8FFD, 0xD7B7, + 0x9000, 0xCDCB, + 0x9001, 0xCBCD, + 0x9002, 0xCACA, + 0x9003, 0xCCD3, + 0x9004, 0xE5CC, + 0x9005, 0xE5CB, + 0x9006, 0xC4E6, + 0x9009, 0xD1A1, + 0x900A, 0xD1B7, + 0x900B, 0xE5CD, + 0x900D, 0xE5D0, + 0x900F, 0xCDB8, + 0x9010, 0xD6F0, + 0x9011, 0xE5CF, + 0x9012, 0xB5DD, + 0x9014, 0xCDBE, + 0x9016, 0xE5D1, + 0x9017, 0xB6BA, + 0x901A, 0xCDA8, + 0x901B, 0xB9E4, + 0x901D, 0xCAC5, + 0x901E, 0xB3D1, + 0x901F, 0xCBD9, + 0x9020, 0xD4EC, + 0x9021, 0xE5D2, + 0x9022, 0xB7EA, + 0x9026, 0xE5CE, + 0x902D, 0xE5D5, + 0x902E, 0xB4FE, + 0x902F, 0xE5D6, + 0x9035, 0xE5D3, + 0x9036, 0xE5D4, + 0x9038, 0xD2DD, + 0x903B, 0xC2DF, + 0x903C, 0xB1C6, + 0x903E, 0xD3E2, + 0x9041, 0xB6DD, + 0x9042, 0xCBEC, + 0x9044, 0xE5D7, + 0x9047, 0xD3F6, + 0x904D, 0xB1E9, + 0x904F, 0xB6F4, + 0x9050, 0xE5DA, + 0x9051, 0xE5D8, + 0x9052, 0xE5D9, + 0x9053, 0xB5C0, + 0x9057, 0xD2C5, + 0x9058, 0xE5DC, + 0x905B, 0xE5DE, + 0x9062, 0xE5DD, + 0x9063, 0xC7B2, + 0x9065, 0xD2A3, + 0x9068, 0xE5DB, + 0x906D, 0xD4E2, + 0x906E, 0xD5DA, + 0x9074, 0xE5E0, + 0x9075, 0xD7F1, + 0x907D, 0xE5E1, + 0x907F, 0xB1DC, + 0x9080, 0xD1FB, + 0x9082, 0xE5E2, + 0x9083, 0xE5E4, + 0x9088, 0xE5E3, + 0x908B, 0xE5E5, + 0x9091, 0xD2D8, + 0x9093, 0xB5CB, + 0x9095, 0xE7DF, + 0x9097, 0xDAF5, + 0x9099, 0xDAF8, + 0x909B, 0xDAF6, + 0x909D, 0xDAF7, + 0x90A1, 0xDAFA, + 0x90A2, 0xD0CF, + 0x90A3, 0xC4C7, + 0x90A6, 0xB0EE, + 0x90AA, 0xD0B0, + 0x90AC, 0xDAF9, + 0x90AE, 0xD3CA, + 0x90AF, 0xBAAA, + 0x90B0, 0xDBA2, + 0x90B1, 0xC7F1, + 0x90B3, 0xDAFC, + 0x90B4, 0xDAFB, + 0x90B5, 0xC9DB, + 0x90B6, 0xDAFD, + 0x90B8, 0xDBA1, + 0x90B9, 0xD7DE, + 0x90BA, 0xDAFE, + 0x90BB, 0xC1DA, + 0x90BE, 0xDBA5, + 0x90C1, 0xD3F4, + 0x90C4, 0xDBA7, + 0x90C5, 0xDBA4, + 0x90C7, 0xDBA8, + 0x90CA, 0xBDBC, + 0x90CE, 0xC0C9, + 0x90CF, 0xDBA3, + 0x90D0, 0xDBA6, + 0x90D1, 0xD6A3, + 0x90D3, 0xDBA9, + 0x90D7, 0xDBAD, + 0x90DB, 0xDBAE, + 0x90DC, 0xDBAC, + 0x90DD, 0xBAC2, + 0x90E1, 0xBFA4, + 0x90E2, 0xDBAB, + 0x90E6, 0xDBAA, + 0x90E7, 0xD4C7, + 0x90E8, 0xB2BF, + 0x90EB, 0xDBAF, + 0x90ED, 0xB9F9, + 0x90EF, 0xDBB0, + 0x90F4, 0xB3BB, + 0x90F8, 0xB5A6, + 0x90FD, 0xB6BC, + 0x90FE, 0xDBB1, + 0x9102, 0xB6F5, + 0x9104, 0xDBB2, + 0x9119, 0xB1C9, + 0x911E, 0xDBB4, + 0x9122, 0xDBB3, + 0x9123, 0xDBB5, + 0x912F, 0xDBB7, + 0x9131, 0xDBB6, + 0x9139, 0xDBB8, + 0x9143, 0xDBB9, + 0x9146, 0xDBBA, + 0x9149, 0xD3CF, + 0x914A, 0xF4FA, + 0x914B, 0xC7F5, + 0x914C, 0xD7C3, + 0x914D, 0xC5E4, + 0x914E, 0xF4FC, + 0x914F, 0xF4FD, + 0x9150, 0xF4FB, + 0x9152, 0xBEC6, + 0x9157, 0xD0EF, + 0x915A, 0xB7D3, + 0x915D, 0xD4CD, + 0x915E, 0xCCAA, + 0x9161, 0xF5A2, + 0x9162, 0xF5A1, + 0x9163, 0xBAA8, + 0x9164, 0xF4FE, + 0x9165, 0xCBD6, + 0x9169, 0xF5A4, + 0x916A, 0xC0D2, + 0x916C, 0xB3EA, + 0x916E, 0xCDAA, + 0x916F, 0xF5A5, + 0x9170, 0xF5A3, + 0x9171, 0xBDB4, + 0x9172, 0xF5A8, + 0x9174, 0xF5A9, + 0x9175, 0xBDCD, + 0x9176, 0xC3B8, + 0x9177, 0xBFE1, + 0x9178, 0xCBE1, + 0x9179, 0xF5AA, + 0x917D, 0xF5A6, + 0x917E, 0xF5A7, + 0x917F, 0xC4F0, + 0x9185, 0xF5AC, + 0x9187, 0xB4BC, + 0x9189, 0xD7ED, + 0x918B, 0xB4D7, + 0x918C, 0xF5AB, + 0x918D, 0xF5AE, + 0x9190, 0xF5AD, + 0x9191, 0xF5AF, + 0x9192, 0xD0D1, + 0x919A, 0xC3D1, + 0x919B, 0xC8A9, + 0x91A2, 0xF5B0, + 0x91A3, 0xF5B1, + 0x91AA, 0xF5B2, + 0x91AD, 0xF5B3, + 0x91AE, 0xF5B4, + 0x91AF, 0xF5B5, + 0x91B4, 0xF5B7, + 0x91B5, 0xF5B6, + 0x91BA, 0xF5B8, + 0x91C7, 0xB2C9, + 0x91C9, 0xD3D4, + 0x91CA, 0xCACD, + 0x91CC, 0xC0EF, + 0x91CD, 0xD6D8, + 0x91CE, 0xD2B0, + 0x91CF, 0xC1BF, + 0x91D1, 0xBDF0, + 0x91DC, 0xB8AA, + 0x9274, 0xBCF8, + 0x928E, 0xF6C6, + 0x92AE, 0xF6C7, + 0x92C8, 0xF6C8, + 0x933E, 0xF6C9, + 0x936A, 0xF6CA, + 0x938F, 0xF6CC, + 0x93CA, 0xF6CB, + 0x93D6, 0xF7E9, + 0x943E, 0xF6CD, + 0x946B, 0xF6CE, + 0x9485, 0xEEC4, + 0x9486, 0xEEC5, + 0x9487, 0xEEC6, + 0x9488, 0xD5EB, + 0x9489, 0xB6A4, + 0x948A, 0xEEC8, + 0x948B, 0xEEC7, + 0x948C, 0xEEC9, + 0x948D, 0xEECA, + 0x948E, 0xC7A5, + 0x948F, 0xEECB, + 0x9490, 0xEECC, + 0x9492, 0xB7B0, + 0x9493, 0xB5F6, + 0x9494, 0xEECD, + 0x9495, 0xEECF, + 0x9497, 0xEECE, + 0x9499, 0xB8C6, + 0x949A, 0xEED0, + 0x949B, 0xEED1, + 0x949C, 0xEED2, + 0x949D, 0xB6DB, + 0x949E, 0xB3AE, + 0x949F, 0xD6D3, + 0x94A0, 0xC4C6, + 0x94A1, 0xB1B5, + 0x94A2, 0xB8D6, + 0x94A3, 0xEED3, + 0x94A4, 0xEED4, + 0x94A5, 0xD4BF, + 0x94A6, 0xC7D5, + 0x94A7, 0xBEFB, + 0x94A8, 0xCED9, + 0x94A9, 0xB9B3, + 0x94AA, 0xEED6, + 0x94AB, 0xEED5, + 0x94AC, 0xEED8, + 0x94AD, 0xEED7, + 0x94AE, 0xC5A5, + 0x94AF, 0xEED9, + 0x94B0, 0xEEDA, + 0x94B1, 0xC7AE, + 0x94B2, 0xEEDB, + 0x94B3, 0xC7AF, + 0x94B4, 0xEEDC, + 0x94B5, 0xB2A7, + 0x94B6, 0xEEDD, + 0x94B7, 0xEEDE, + 0x94B8, 0xEEDF, + 0x94B9, 0xEEE0, + 0x94BA, 0xEEE1, + 0x94BB, 0xD7EA, + 0x94BC, 0xEEE2, + 0x94BD, 0xEEE3, + 0x94BE, 0xBCD8, + 0x94BF, 0xEEE4, + 0x94C0, 0xD3CB, + 0x94C1, 0xCCFA, + 0x94C2, 0xB2AC, + 0x94C3, 0xC1E5, + 0x94C4, 0xEEE5, + 0x94C5, 0xC7A6, + 0x94C6, 0xC3AD, + 0x94C8, 0xEEE6, + 0x94C9, 0xEEE7, + 0x94CA, 0xEEE8, + 0x94CB, 0xEEE9, + 0x94CC, 0xEEEA, + 0x94CD, 0xEEEB, + 0x94CE, 0xEEEC, + 0x94D0, 0xEEED, + 0x94D1, 0xEEEE, + 0x94D2, 0xEEEF, + 0x94D5, 0xEEF0, + 0x94D6, 0xEEF1, + 0x94D7, 0xEEF2, + 0x94D8, 0xEEF4, + 0x94D9, 0xEEF3, + 0x94DB, 0xEEF5, + 0x94DC, 0xCDAD, + 0x94DD, 0xC2C1, + 0x94DE, 0xEEF6, + 0x94DF, 0xEEF7, + 0x94E0, 0xEEF8, + 0x94E1, 0xD5A1, + 0x94E2, 0xEEF9, + 0x94E3, 0xCFB3, + 0x94E4, 0xEEFA, + 0x94E5, 0xEEFB, + 0x94E7, 0xEEFC, + 0x94E8, 0xEEFD, + 0x94E9, 0xEFA1, + 0x94EA, 0xEEFE, + 0x94EB, 0xEFA2, + 0x94EC, 0xB8F5, + 0x94ED, 0xC3FA, + 0x94EE, 0xEFA3, + 0x94EF, 0xEFA4, + 0x94F0, 0xBDC2, + 0x94F1, 0xD2BF, + 0x94F2, 0xB2F9, + 0x94F3, 0xEFA5, + 0x94F4, 0xEFA6, + 0x94F5, 0xEFA7, + 0x94F6, 0xD2F8, + 0x94F7, 0xEFA8, + 0x94F8, 0xD6FD, + 0x94F9, 0xEFA9, + 0x94FA, 0xC6CC, + 0x94FC, 0xEFAA, + 0x94FD, 0xEFAB, + 0x94FE, 0xC1B4, + 0x94FF, 0xEFAC, + 0x9500, 0xCFFA, + 0x9501, 0xCBF8, + 0x9502, 0xEFAE, + 0x9503, 0xEFAD, + 0x9504, 0xB3FA, + 0x9505, 0xB9F8, + 0x9506, 0xEFAF, + 0x9507, 0xEFB0, + 0x9508, 0xD0E2, + 0x9509, 0xEFB1, + 0x950A, 0xEFB2, + 0x950B, 0xB7E6, + 0x950C, 0xD0BF, + 0x950D, 0xEFB3, + 0x950E, 0xEFB4, + 0x950F, 0xEFB5, + 0x9510, 0xC8F1, + 0x9511, 0xCCE0, + 0x9512, 0xEFB6, + 0x9513, 0xEFB7, + 0x9514, 0xEFB8, + 0x9515, 0xEFB9, + 0x9516, 0xEFBA, + 0x9517, 0xD5E0, + 0x9518, 0xEFBB, + 0x9519, 0xB4ED, + 0x951A, 0xC3AA, + 0x951B, 0xEFBC, + 0x951D, 0xEFBD, + 0x951E, 0xEFBE, + 0x951F, 0xEFBF, + 0x9521, 0xCEFD, + 0x9522, 0xEFC0, + 0x9523, 0xC2E0, + 0x9524, 0xB4B8, + 0x9525, 0xD7B6, + 0x9526, 0xBDF5, + 0x9528, 0xCFC7, + 0x9529, 0xEFC3, + 0x952A, 0xEFC1, + 0x952B, 0xEFC2, + 0x952C, 0xEFC4, + 0x952D, 0xB6A7, + 0x952E, 0xBCFC, + 0x952F, 0xBEE2, + 0x9530, 0xC3CC, + 0x9531, 0xEFC5, + 0x9532, 0xEFC6, + 0x9534, 0xEFC7, + 0x9535, 0xEFCF, + 0x9536, 0xEFC8, + 0x9537, 0xEFC9, + 0x9538, 0xEFCA, + 0x9539, 0xC7C2, + 0x953A, 0xEFF1, + 0x953B, 0xB6CD, + 0x953C, 0xEFCB, + 0x953E, 0xEFCC, + 0x953F, 0xEFCD, + 0x9540, 0xB6C6, + 0x9541, 0xC3BE, + 0x9542, 0xEFCE, + 0x9544, 0xEFD0, + 0x9545, 0xEFD1, + 0x9546, 0xEFD2, + 0x9547, 0xD5F2, + 0x9549, 0xEFD3, + 0x954A, 0xC4F7, + 0x954C, 0xEFD4, + 0x954D, 0xC4F8, + 0x954E, 0xEFD5, + 0x954F, 0xEFD6, + 0x9550, 0xB8E4, + 0x9551, 0xB0F7, + 0x9552, 0xEFD7, + 0x9553, 0xEFD8, + 0x9554, 0xEFD9, + 0x9556, 0xEFDA, + 0x9557, 0xEFDB, + 0x9558, 0xEFDC, + 0x9559, 0xEFDD, + 0x955B, 0xEFDE, + 0x955C, 0xBEB5, + 0x955D, 0xEFE1, + 0x955E, 0xEFDF, + 0x955F, 0xEFE0, + 0x9561, 0xEFE2, + 0x9562, 0xEFE3, + 0x9563, 0xC1CD, + 0x9564, 0xEFE4, + 0x9565, 0xEFE5, + 0x9566, 0xEFE6, + 0x9567, 0xEFE7, + 0x9568, 0xEFE8, + 0x9569, 0xEFE9, + 0x956A, 0xEFEA, + 0x956B, 0xEFEB, + 0x956C, 0xEFEC, + 0x956D, 0xC0D8, + 0x956F, 0xEFED, + 0x9570, 0xC1AD, + 0x9571, 0xEFEE, + 0x9572, 0xEFEF, + 0x9573, 0xEFF0, + 0x9576, 0xCFE2, + 0x957F, 0xB3A4, + 0x95E8, 0xC3C5, + 0x95E9, 0xE3C5, + 0x95EA, 0xC9C1, + 0x95EB, 0xE3C6, + 0x95ED, 0xB1D5, + 0x95EE, 0xCECA, + 0x95EF, 0xB4B3, + 0x95F0, 0xC8F2, + 0x95F1, 0xE3C7, + 0x95F2, 0xCFD0, + 0x95F3, 0xE3C8, + 0x95F4, 0xBCE4, + 0x95F5, 0xE3C9, + 0x95F6, 0xE3CA, + 0x95F7, 0xC3C6, + 0x95F8, 0xD5A2, + 0x95F9, 0xC4D6, + 0x95FA, 0xB9EB, + 0x95FB, 0xCEC5, + 0x95FC, 0xE3CB, + 0x95FD, 0xC3F6, + 0x95FE, 0xE3CC, + 0x9600, 0xB7A7, + 0x9601, 0xB8F3, + 0x9602, 0xBAD2, + 0x9603, 0xE3CD, + 0x9604, 0xE3CE, + 0x9605, 0xD4C4, + 0x9606, 0xE3CF, + 0x9608, 0xE3D0, + 0x9609, 0xD1CB, + 0x960A, 0xE3D1, + 0x960B, 0xE3D2, + 0x960C, 0xE3D3, + 0x960D, 0xE3D4, + 0x960E, 0xD1D6, + 0x960F, 0xE3D5, + 0x9610, 0xB2FB, + 0x9611, 0xC0BB, + 0x9612, 0xE3D6, + 0x9614, 0xC0AB, + 0x9615, 0xE3D7, + 0x9616, 0xE3D8, + 0x9617, 0xE3D9, + 0x9619, 0xE3DA, + 0x961A, 0xE3DB, + 0x961C, 0xB8B7, + 0x961D, 0xDAE2, + 0x961F, 0xB6D3, + 0x9621, 0xDAE4, + 0x9622, 0xDAE3, + 0x962A, 0xDAE6, + 0x962E, 0xC8EE, + 0x9631, 0xDAE5, + 0x9632, 0xB7C0, + 0x9633, 0xD1F4, + 0x9634, 0xD2F5, + 0x9635, 0xD5F3, + 0x9636, 0xBDD7, + 0x963B, 0xD7E8, + 0x963C, 0xDAE8, + 0x963D, 0xDAE7, + 0x963F, 0xB0A2, + 0x9640, 0xCDD3, + 0x9642, 0xDAE9, + 0x9644, 0xB8BD, + 0x9645, 0xBCCA, + 0x9646, 0xC2BD, + 0x9647, 0xC2A4, + 0x9648, 0xB3C2, + 0x9649, 0xDAEA, + 0x964B, 0xC2AA, + 0x964C, 0xC4B0, + 0x964D, 0xBDB5, + 0x9650, 0xCFDE, + 0x9654, 0xDAEB, + 0x9655, 0xC9C2, + 0x965B, 0xB1DD, + 0x965F, 0xDAEC, + 0x9661, 0xB6B8, + 0x9662, 0xD4BA, + 0x9664, 0xB3FD, + 0x9667, 0xDAED, + 0x9668, 0xD4C9, + 0x9669, 0xCFD5, + 0x966A, 0xC5E3, + 0x966C, 0xDAEE, + 0x9672, 0xDAEF, + 0x9674, 0xDAF0, + 0x9675, 0xC1EA, + 0x9676, 0xCCD5, + 0x9677, 0xCFDD, + 0x9685, 0xD3E7, + 0x9686, 0xC2A1, + 0x9688, 0xDAF1, + 0x968B, 0xCBE5, + 0x968D, 0xDAF2, + 0x968F, 0xCBE6, + 0x9690, 0xD2FE, + 0x9694, 0xB8F4, + 0x9697, 0xDAF3, + 0x9698, 0xB0AF, + 0x9699, 0xCFB6, + 0x969C, 0xD5CF, + 0x96A7, 0xCBED, + 0x96B0, 0xDAF4, + 0x96B3, 0xE3C4, + 0x96B6, 0xC1A5, + 0x96B9, 0xF6BF, + 0x96BC, 0xF6C0, + 0x96BD, 0xF6C1, + 0x96BE, 0xC4D1, + 0x96C0, 0xC8B8, + 0x96C1, 0xD1E3, + 0x96C4, 0xD0DB, + 0x96C5, 0xD1C5, + 0x96C6, 0xBCAF, + 0x96C7, 0xB9CD, + 0x96C9, 0xEFF4, + 0x96CC, 0xB4C6, + 0x96CD, 0xD3BA, + 0x96CE, 0xF6C2, + 0x96CF, 0xB3FB, + 0x96D2, 0xF6C3, + 0x96D5, 0xB5F1, + 0x96E0, 0xF6C5, + 0x96E8, 0xD3EA, + 0x96E9, 0xF6A7, + 0x96EA, 0xD1A9, + 0x96EF, 0xF6A9, + 0x96F3, 0xF6A8, + 0x96F6, 0xC1E3, + 0x96F7, 0xC0D7, + 0x96F9, 0xB1A2, + 0x96FE, 0xCEED, + 0x9700, 0xD0E8, + 0x9701, 0xF6AB, + 0x9704, 0xCFF6, + 0x9706, 0xF6AA, + 0x9707, 0xD5F0, + 0x9708, 0xF6AC, + 0x9709, 0xC3B9, + 0x970D, 0xBBF4, + 0x970E, 0xF6AE, + 0x970F, 0xF6AD, + 0x9713, 0xC4DE, + 0x9716, 0xC1D8, + 0x971C, 0xCBAA, + 0x971E, 0xCFBC, + 0x972A, 0xF6AF, + 0x972D, 0xF6B0, + 0x9730, 0xF6B1, + 0x9732, 0xC2B6, + 0x9738, 0xB0D4, + 0x9739, 0xC5F9, + 0x973E, 0xF6B2, + 0x9752, 0xC7E0, + 0x9753, 0xF6A6, + 0x9756, 0xBEB8, + 0x9759, 0xBEB2, + 0x975B, 0xB5E5, + 0x975E, 0xB7C7, + 0x9760, 0xBFBF, + 0x9761, 0xC3D2, + 0x9762, 0xC3E6, + 0x9765, 0xD8CC, + 0x9769, 0xB8EF, + 0x9773, 0xBDF9, + 0x9774, 0xD1A5, + 0x9776, 0xB0D0, + 0x977C, 0xF7B0, + 0x9785, 0xF7B1, + 0x978B, 0xD0AC, + 0x978D, 0xB0B0, + 0x9791, 0xF7B2, + 0x9792, 0xF7B3, + 0x9794, 0xF7B4, + 0x9798, 0xC7CA, + 0x97A0, 0xBECF, + 0x97A3, 0xF7B7, + 0x97AB, 0xF7B6, + 0x97AD, 0xB1DE, + 0x97AF, 0xF7B5, + 0x97B2, 0xF7B8, + 0x97B4, 0xF7B9, + 0x97E6, 0xCEA4, + 0x97E7, 0xC8CD, + 0x97E9, 0xBAAB, + 0x97EA, 0xE8B8, + 0x97EB, 0xE8B9, + 0x97EC, 0xE8BA, + 0x97ED, 0xBEC2, + 0x97F3, 0xD2F4, + 0x97F5, 0xD4CF, + 0x97F6, 0xC9D8, + 0x9875, 0xD2B3, + 0x9876, 0xB6A5, + 0x9877, 0xC7EA, + 0x9878, 0xF1FC, + 0x9879, 0xCFEE, + 0x987A, 0xCBB3, + 0x987B, 0xD0EB, + 0x987C, 0xE7EF, + 0x987D, 0xCDE7, + 0x987E, 0xB9CB, + 0x987F, 0xB6D9, + 0x9880, 0xF1FD, + 0x9881, 0xB0E4, + 0x9882, 0xCBCC, + 0x9883, 0xF1FE, + 0x9884, 0xD4A4, + 0x9885, 0xC2AD, + 0x9886, 0xC1EC, + 0x9887, 0xC6C4, + 0x9888, 0xBEB1, + 0x9889, 0xF2A1, + 0x988A, 0xBCD5, + 0x988C, 0xF2A2, + 0x988D, 0xF2A3, + 0x988F, 0xF2A4, + 0x9890, 0xD2C3, + 0x9891, 0xC6B5, + 0x9893, 0xCDC7, + 0x9894, 0xF2A5, + 0x9896, 0xD3B1, + 0x9897, 0xBFC5, + 0x9898, 0xCCE2, + 0x989A, 0xF2A6, + 0x989B, 0xF2A7, + 0x989C, 0xD1D5, + 0x989D, 0xB6EE, + 0x989E, 0xF2A8, + 0x989F, 0xF2A9, + 0x98A0, 0xB5DF, + 0x98A1, 0xF2AA, + 0x98A2, 0xF2AB, + 0x98A4, 0xB2FC, + 0x98A5, 0xF2AC, + 0x98A6, 0xF2AD, + 0x98A7, 0xC8A7, + 0x98CE, 0xB7E7, + 0x98D1, 0xECA9, + 0x98D2, 0xECAA, + 0x98D3, 0xECAB, + 0x98D5, 0xECAC, + 0x98D8, 0xC6AE, + 0x98D9, 0xECAD, + 0x98DA, 0xECAE, + 0x98DE, 0xB7C9, + 0x98DF, 0xCAB3, + 0x98E7, 0xE2B8, + 0x98E8, 0xF7CF, + 0x990D, 0xF7D0, + 0x9910, 0xB2CD, + 0x992E, 0xF7D1, + 0x9954, 0xF7D3, + 0x9955, 0xF7D2, + 0x9963, 0xE2BB, + 0x9965, 0xBCA2, + 0x9967, 0xE2BC, + 0x9968, 0xE2BD, + 0x9969, 0xE2BE, + 0x996A, 0xE2BF, + 0x996B, 0xE2C0, + 0x996C, 0xE2C1, + 0x996D, 0xB7B9, + 0x996E, 0xD2FB, + 0x996F, 0xBDA4, + 0x9970, 0xCACE, + 0x9971, 0xB1A5, + 0x9972, 0xCBC7, + 0x9974, 0xE2C2, + 0x9975, 0xB6FC, + 0x9976, 0xC8C4, + 0x9977, 0xE2C3, + 0x997A, 0xBDC8, + 0x997C, 0xB1FD, + 0x997D, 0xE2C4, + 0x997F, 0xB6F6, + 0x9980, 0xE2C5, + 0x9981, 0xC4D9, + 0x9984, 0xE2C6, + 0x9985, 0xCFDA, + 0x9986, 0xB9DD, + 0x9987, 0xE2C7, + 0x9988, 0xC0A1, + 0x998A, 0xE2C8, + 0x998B, 0xB2F6, + 0x998D, 0xE2C9, + 0x998F, 0xC1F3, + 0x9990, 0xE2CA, + 0x9991, 0xE2CB, + 0x9992, 0xC2F8, + 0x9993, 0xE2CC, + 0x9994, 0xE2CD, + 0x9995, 0xE2CE, + 0x9996, 0xCAD7, + 0x9997, 0xD8B8, + 0x9998, 0xD9E5, + 0x9999, 0xCFE3, + 0x99A5, 0xF0A5, + 0x99A8, 0xDCB0, + 0x9A6C, 0xC2ED, + 0x9A6D, 0xD4A6, + 0x9A6E, 0xCDD4, + 0x9A6F, 0xD1B1, + 0x9A70, 0xB3DB, + 0x9A71, 0xC7FD, + 0x9A73, 0xB2B5, + 0x9A74, 0xC2BF, + 0x9A75, 0xE6E0, + 0x9A76, 0xCABB, + 0x9A77, 0xE6E1, + 0x9A78, 0xE6E2, + 0x9A79, 0xBED4, + 0x9A7A, 0xE6E3, + 0x9A7B, 0xD7A4, + 0x9A7C, 0xCDD5, + 0x9A7D, 0xE6E5, + 0x9A7E, 0xBCDD, + 0x9A7F, 0xE6E4, + 0x9A80, 0xE6E6, + 0x9A81, 0xE6E7, + 0x9A82, 0xC2EE, + 0x9A84, 0xBDBE, + 0x9A85, 0xE6E8, + 0x9A86, 0xC2E6, + 0x9A87, 0xBAA7, + 0x9A88, 0xE6E9, + 0x9A8A, 0xE6EA, + 0x9A8B, 0xB3D2, + 0x9A8C, 0xD1E9, + 0x9A8F, 0xBFA5, + 0x9A90, 0xE6EB, + 0x9A91, 0xC6EF, + 0x9A92, 0xE6EC, + 0x9A93, 0xE6ED, + 0x9A96, 0xE6EE, + 0x9A97, 0xC6AD, + 0x9A98, 0xE6EF, + 0x9A9A, 0xC9A7, + 0x9A9B, 0xE6F0, + 0x9A9C, 0xE6F1, + 0x9A9D, 0xE6F2, + 0x9A9E, 0xE5B9, + 0x9A9F, 0xE6F3, + 0x9AA0, 0xE6F4, + 0x9AA1, 0xC2E2, + 0x9AA2, 0xE6F5, + 0x9AA3, 0xE6F6, + 0x9AA4, 0xD6E8, + 0x9AA5, 0xE6F7, + 0x9AA7, 0xE6F8, + 0x9AA8, 0xB9C7, + 0x9AB0, 0xF7BB, + 0x9AB1, 0xF7BA, + 0x9AB6, 0xF7BE, + 0x9AB7, 0xF7BC, + 0x9AB8, 0xBAA1, + 0x9ABA, 0xF7BF, + 0x9ABC, 0xF7C0, + 0x9AC0, 0xF7C2, + 0x9AC1, 0xF7C1, + 0x9AC2, 0xF7C4, + 0x9AC5, 0xF7C3, + 0x9ACB, 0xF7C5, + 0x9ACC, 0xF7C6, + 0x9AD1, 0xF7C7, + 0x9AD3, 0xCBE8, + 0x9AD8, 0xB8DF, + 0x9ADF, 0xF7D4, + 0x9AE1, 0xF7D5, + 0x9AE6, 0xF7D6, + 0x9AEB, 0xF7D8, + 0x9AED, 0xF7DA, + 0x9AEF, 0xF7D7, + 0x9AF9, 0xF7DB, + 0x9AFB, 0xF7D9, + 0x9B03, 0xD7D7, + 0x9B08, 0xF7DC, + 0x9B0F, 0xF7DD, + 0x9B13, 0xF7DE, + 0x9B1F, 0xF7DF, + 0x9B23, 0xF7E0, + 0x9B2F, 0xDBCB, + 0x9B32, 0xD8AA, + 0x9B3B, 0xE5F7, + 0x9B3C, 0xB9ED, + 0x9B41, 0xBFFD, + 0x9B42, 0xBBEA, + 0x9B43, 0xF7C9, + 0x9B44, 0xC6C7, + 0x9B45, 0xF7C8, + 0x9B47, 0xF7CA, + 0x9B48, 0xF7CC, + 0x9B49, 0xF7CB, + 0x9B4D, 0xF7CD, + 0x9B4F, 0xCEBA, + 0x9B51, 0xF7CE, + 0x9B54, 0xC4A7, + 0x9C7C, 0xD3E3, + 0x9C7F, 0xF6CF, + 0x9C81, 0xC2B3, + 0x9C82, 0xF6D0, + 0x9C85, 0xF6D1, + 0x9C86, 0xF6D2, + 0x9C87, 0xF6D3, + 0x9C88, 0xF6D4, + 0x9C8B, 0xF6D6, + 0x9C8D, 0xB1AB, + 0x9C8E, 0xF6D7, + 0x9C90, 0xF6D8, + 0x9C91, 0xF6D9, + 0x9C92, 0xF6DA, + 0x9C94, 0xF6DB, + 0x9C95, 0xF6DC, + 0x9C9A, 0xF6DD, + 0x9C9B, 0xF6DE, + 0x9C9C, 0xCFCA, + 0x9C9E, 0xF6DF, + 0x9C9F, 0xF6E0, + 0x9CA0, 0xF6E1, + 0x9CA1, 0xF6E2, + 0x9CA2, 0xF6E3, + 0x9CA3, 0xF6E4, + 0x9CA4, 0xC0F0, + 0x9CA5, 0xF6E5, + 0x9CA6, 0xF6E6, + 0x9CA7, 0xF6E7, + 0x9CA8, 0xF6E8, + 0x9CA9, 0xF6E9, + 0x9CAB, 0xF6EA, + 0x9CAD, 0xF6EB, + 0x9CAE, 0xF6EC, + 0x9CB0, 0xF6ED, + 0x9CB1, 0xF6EE, + 0x9CB2, 0xF6EF, + 0x9CB3, 0xF6F0, + 0x9CB4, 0xF6F1, + 0x9CB5, 0xF6F2, + 0x9CB6, 0xF6F3, + 0x9CB7, 0xF6F4, + 0x9CB8, 0xBEA8, + 0x9CBA, 0xF6F5, + 0x9CBB, 0xF6F6, + 0x9CBC, 0xF6F7, + 0x9CBD, 0xF6F8, + 0x9CC3, 0xC8FA, + 0x9CC4, 0xF6F9, + 0x9CC5, 0xF6FA, + 0x9CC6, 0xF6FB, + 0x9CC7, 0xF6FC, + 0x9CCA, 0xF6FD, + 0x9CCB, 0xF6FE, + 0x9CCC, 0xF7A1, + 0x9CCD, 0xF7A2, + 0x9CCE, 0xF7A3, + 0x9CCF, 0xF7A4, + 0x9CD0, 0xF7A5, + 0x9CD3, 0xF7A6, + 0x9CD4, 0xF7A7, + 0x9CD5, 0xF7A8, + 0x9CD6, 0xB1EE, + 0x9CD7, 0xF7A9, + 0x9CD8, 0xF7AA, + 0x9CD9, 0xF7AB, + 0x9CDC, 0xF7AC, + 0x9CDD, 0xF7AD, + 0x9CDE, 0xC1DB, + 0x9CDF, 0xF7AE, + 0x9CE2, 0xF7AF, + 0x9E1F, 0xC4F1, + 0x9E20, 0xF0AF, + 0x9E21, 0xBCA6, + 0x9E22, 0xF0B0, + 0x9E23, 0xC3F9, + 0x9E25, 0xC5B8, + 0x9E26, 0xD1BB, + 0x9E28, 0xF0B1, + 0x9E29, 0xF0B2, + 0x9E2A, 0xF0B3, + 0x9E2B, 0xF0B4, + 0x9E2C, 0xF0B5, + 0x9E2D, 0xD1BC, + 0x9E2F, 0xD1EC, + 0x9E31, 0xF0B7, + 0x9E32, 0xF0B6, + 0x9E33, 0xD4A7, + 0x9E35, 0xCDD2, + 0x9E36, 0xF0B8, + 0x9E37, 0xF0BA, + 0x9E38, 0xF0B9, + 0x9E39, 0xF0BB, + 0x9E3A, 0xF0BC, + 0x9E3D, 0xB8EB, + 0x9E3E, 0xF0BD, + 0x9E3F, 0xBAE8, + 0x9E41, 0xF0BE, + 0x9E42, 0xF0BF, + 0x9E43, 0xBEE9, + 0x9E44, 0xF0C0, + 0x9E45, 0xB6EC, + 0x9E46, 0xF0C1, + 0x9E47, 0xF0C2, + 0x9E48, 0xF0C3, + 0x9E49, 0xF0C4, + 0x9E4A, 0xC8B5, + 0x9E4B, 0xF0C5, + 0x9E4C, 0xF0C6, + 0x9E4E, 0xF0C7, + 0x9E4F, 0xC5F4, + 0x9E51, 0xF0C8, + 0x9E55, 0xF0C9, + 0x9E57, 0xF0CA, + 0x9E58, 0xF7BD, + 0x9E5A, 0xF0CB, + 0x9E5B, 0xF0CC, + 0x9E5C, 0xF0CD, + 0x9E5E, 0xF0CE, + 0x9E63, 0xF0CF, + 0x9E64, 0xBAD7, + 0x9E66, 0xF0D0, + 0x9E67, 0xF0D1, + 0x9E68, 0xF0D2, + 0x9E69, 0xF0D3, + 0x9E6A, 0xF0D4, + 0x9E6B, 0xF0D5, + 0x9E6C, 0xF0D6, + 0x9E6D, 0xF0D8, + 0x9E70, 0xD3A5, + 0x9E71, 0xF0D7, + 0x9E73, 0xF0D9, + 0x9E7E, 0xF5BA, + 0x9E7F, 0xC2B9, + 0x9E82, 0xF7E4, + 0x9E87, 0xF7E5, + 0x9E88, 0xF7E6, + 0x9E8B, 0xF7E7, + 0x9E92, 0xF7E8, + 0x9E93, 0xC2B4, + 0x9E9D, 0xF7EA, + 0x9E9F, 0xF7EB, + 0x9EA6, 0xC2F3, + 0x9EB4, 0xF4F0, + 0x9EB8, 0xF4EF, + 0x9EBB, 0xC2E9, + 0x9EBD, 0xF7E1, + 0x9EBE, 0xF7E2, + 0x9EC4, 0xBBC6, + 0x9EC9, 0xD9E4, + 0x9ECD, 0xCAF2, + 0x9ECE, 0xC0E8, + 0x9ECF, 0xF0A4, + 0x9ED1, 0xBADA, + 0x9ED4, 0xC7AD, + 0x9ED8, 0xC4AC, + 0x9EDB, 0xF7EC, + 0x9EDC, 0xF7ED, + 0x9EDD, 0xF7EE, + 0x9EDF, 0xF7F0, + 0x9EE0, 0xF7EF, + 0x9EE2, 0xF7F1, + 0x9EE5, 0xF7F4, + 0x9EE7, 0xF7F3, + 0x9EE9, 0xF7F2, + 0x9EEA, 0xF7F5, + 0x9EEF, 0xF7F6, + 0x9EF9, 0xEDE9, + 0x9EFB, 0xEDEA, + 0x9EFC, 0xEDEB, + 0x9EFE, 0xF6BC, + 0x9F0B, 0xF6BD, + 0x9F0D, 0xF6BE, + 0x9F0E, 0xB6A6, + 0x9F10, 0xD8BE, + 0x9F13, 0xB9C4, + 0x9F17, 0xD8BB, + 0x9F19, 0xDCB1, + 0x9F20, 0xCAF3, + 0x9F22, 0xF7F7, + 0x9F2C, 0xF7F8, + 0x9F2F, 0xF7F9, + 0x9F37, 0xF7FB, + 0x9F39, 0xF7FA, + 0x9F3B, 0xB1C7, + 0x9F3D, 0xF7FC, + 0x9F3E, 0xF7FD, + 0x9F44, 0xF7FE, + 0x9F50, 0xC6EB, + 0x9F51, 0xECB4, + 0x9F7F, 0xB3DD, + 0x9F80, 0xF6B3, + 0x9F83, 0xF6B4, + 0x9F84, 0xC1E4, + 0x9F85, 0xF6B5, + 0x9F86, 0xF6B6, + 0x9F87, 0xF6B7, + 0x9F88, 0xF6B8, + 0x9F89, 0xF6B9, + 0x9F8A, 0xF6BA, + 0x9F8B, 0xC8A3, + 0x9F8C, 0xF6BB, + 0x9F99, 0xC1FA, + 0x9F9A, 0xB9A8, + 0x9F9B, 0xEDE8, + 0x9F9F, 0xB9EA, + 0x9FA0, 0xD9DF, + 0xFF01, 0xA3A1, + 0xFF02, 0xA3A2, + 0xFF03, 0xA3A3, + 0xFF04, 0xA1E7, + 0xFF05, 0xA3A5, + 0xFF06, 0xA3A6, + 0xFF07, 0xA3A7, + 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, + 0xFF0A, 0xA3AA, + 0xFF0B, 0xA3AB, + 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, + 0xFF0E, 0xA3AE, + 0xFF0F, 0xA3AF, + 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, + 0xFF12, 0xA3B2, + 0xFF13, 0xA3B3, + 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, + 0xFF16, 0xA3B6, + 0xFF17, 0xA3B7, + 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, + 0xFF1A, 0xA3BA, + 0xFF1B, 0xA3BB, + 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, + 0xFF1E, 0xA3BE, + 0xFF1F, 0xA3BF, + 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, + 0xFF22, 0xA3C2, + 0xFF23, 0xA3C3, + 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, + 0xFF26, 0xA3C6, + 0xFF27, 0xA3C7, + 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, + 0xFF2A, 0xA3CA, + 0xFF2B, 0xA3CB, + 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, + 0xFF2E, 0xA3CE, + 0xFF2F, 0xA3CF, + 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, + 0xFF32, 0xA3D2, + 0xFF33, 0xA3D3, + 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, + 0xFF36, 0xA3D6, + 0xFF37, 0xA3D7, + 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, + 0xFF3A, 0xA3DA, + 0xFF3B, 0xA3DB, + 0xFF3C, 0xA3DC, + 0xFF3D, 0xA3DD, + 0xFF3E, 0xA3DE, + 0xFF3F, 0xA3DF, + 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, + 0xFF42, 0xA3E2, + 0xFF43, 0xA3E3, + 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, + 0xFF46, 0xA3E6, + 0xFF47, 0xA3E7, + 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, + 0xFF4A, 0xA3EA, + 0xFF4B, 0xA3EB, + 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, + 0xFF4E, 0xA3EE, + 0xFF4F, 0xA3EF, + 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, + 0xFF52, 0xA3F2, + 0xFF53, 0xA3F3, + 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, + 0xFF56, 0xA3F6, + 0xFF57, 0xA3F7, + 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, + 0xFF5A, 0xA3FA, + 0xFF5B, 0xA3FB, + 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, + 0xFF5E, 0xA1AB, + 0xFFE0, 0xA1E9, + 0xFFE1, 0xA1EA, + 0xFFE3, 0xA3FE, + 0xFFE5, 0xA3A4 +}; diff --git a/backend/gridmtx.c b/backend/gridmtx.c new file mode 100644 index 00000000..f05cd109 --- /dev/null +++ b/backend/gridmtx.c @@ -0,0 +1,1089 @@ +/* gridmtx.c - Grid Matrix + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +/* This file impliments Grid Matrix as specified in + AIM Global Document Number AIMD014 Rev. 1.63 Revised 9 Dec 2008 */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "reedsol.h" +#include "gridmtx.h" +#include "gb2312.h" + +int number_lat(int gbdata[], int length, int position) +{ + /* Attempt to calculate the 'cost' of using numeric mode from a given position in number of bits */ + /* Also ensures that numeric mode is not selected when it cannot be used: for example in + a string which has "2.2.0" (cannot have more than one non-numeric character for each + block of three numeric characters) */ + int sp; + int numb = 0, nonum = 0, done; + int tally = 0; + + sp = position; + + do { + done = 0; + + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { numb++; done = 1; } + switch(gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + nonum++; + done = 1; + } + if((sp + 1) < length) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + nonum++; + done = 1; + sp++; + } + } + + if(done == 0) { + tally += 80; + } else { + if(numb == 3) { + if(nonum == 0) { + tally += 10; + } + if(nonum == 1) { + tally += 20; + } + if(nonum > 1) { + tally += 80; + } + numb = 0; + nonum = 0; + } + } + + sp++; + } while ((sp < length) && (sp <= (position + 8))); + + if(numb == 0) { + tally += 80; + } + + if(numb > 1) { + if(nonum == 0) { + tally += 10; + } + if(nonum == 1) { + tally += 20; + } + if(nonum > 1) { + tally += 80; + } + } + + return tally; +} + +int seek_forward(int gbdata[], int length, int position, int current_mode) +{ + /* In complete contrast to the method recommended in Annex D of the ANSI standard this + code uses a look-ahead test in the same manner as Data Matrix. This decision was made + because the "official" algorithm does not provide clear methods for dealing with all + possible combinations of input data */ + + int number_count, byte_count, mixed_count, upper_count, lower_count, chinese_count; + int sp, best_mode, done; + int best_count, last = -1; + int debug = 0; + + if(gbdata[position] > 0xff) { return GM_CHINESE; } + + switch(current_mode) { + case GM_CHINESE: + number_count = 13; + byte_count = 13; + mixed_count = 13; + upper_count = 13; + lower_count = 13; + chinese_count = 0; + break; + case GM_NUMBER: + number_count = 0; + byte_count = 10; + mixed_count = 10; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_LOWER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 5; + lower_count = 0; + chinese_count = 5; + break; + case GM_UPPER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 0; + lower_count = 5; + chinese_count = 5; + break; + case GM_MIXED: + number_count = 10; + byte_count = 10; + mixed_count = 0; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_BYTE: + number_count = 4; + byte_count = 0; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + default: /* Start of symbol */ + number_count = 4; + byte_count = 4; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + } + + for(sp = position; (sp < length) && (sp <= (position + 8)); sp++) { + + done = 0; + + if(gbdata[sp] >= 0xff) { + byte_count += 17; + mixed_count += 23; + upper_count += 18; + lower_count += 18; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 10; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 10; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + byte_count += 8; + mixed_count += 6; + upper_count += 8; + lower_count += 8; + chinese_count += 13; + done = 1; + } + + if(gbdata[sp] == ' ') { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if(done == 0) { + /* Control character */ + byte_count += 8; + mixed_count += 16; + upper_count += 13; + lower_count += 13; + chinese_count += 13; + } + + if(gbdata[sp] >= 0x7f) { + mixed_count += 20; + upper_count += 20; + lower_count += 20; + } + } + + /* Adjust for */ + for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if((gbdata[sp] == 0x13) && (gbdata[sp] == 0x10)) { + chinese_count -= 13; + } + } + + /* Adjust for double digits */ + for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if(sp != last) { + if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + chinese_count -= 13; + last = sp + 1; + } + } + } + + /* Numeric mode is more complex */ + number_count += number_lat(gbdata, length, position); + + if(debug) { printf("C %d / B %d / M %d / U %d / L %d / N %d\n", chinese_count, byte_count, mixed_count, upper_count, lower_count, number_count); } + + best_count = chinese_count; + best_mode = GM_CHINESE; + + if(byte_count <= best_count) { + best_count = byte_count; + best_mode = GM_BYTE; + } + + if(mixed_count <= best_count) { + best_count = mixed_count; + best_mode = GM_MIXED; + } + + if(upper_count <= best_count) { + best_count = upper_count; + best_mode = GM_UPPER; + } + + if(lower_count <= best_count) { + best_count = lower_count; + best_mode = GM_LOWER; + } + + if(number_count <= best_count) { + best_count = number_count; + best_mode = GM_NUMBER; + } + + return best_mode; +} + +void add_byte_count(char binary[], int byte_count_posn, int byte_count) +{ + /* Add the length indicator for byte encoded blocks */ + if(byte_count & 0x100) { binary[byte_count_posn] = '0'; } else { binary[byte_count_posn] = '1'; } + if(byte_count & 0x80) { binary[byte_count_posn + 1] = '0'; } else { binary[byte_count_posn + 1] = '1'; } + if(byte_count & 0x40) { binary[byte_count_posn + 2] = '0'; } else { binary[byte_count_posn + 2] = '1'; } + if(byte_count & 0x20) { binary[byte_count_posn + 3] = '0'; } else { binary[byte_count_posn + 3] = '1'; } + if(byte_count & 0x10) { binary[byte_count_posn + 4] = '0'; } else { binary[byte_count_posn + 4] = '1'; } + if(byte_count & 0x08) { binary[byte_count_posn + 5] = '0'; } else { binary[byte_count_posn + 5] = '1'; } + if(byte_count & 0x04) { binary[byte_count_posn + 6] = '0'; } else { binary[byte_count_posn + 6] = '1'; } + if(byte_count & 0x02) { binary[byte_count_posn + 7] = '0'; } else { binary[byte_count_posn + 7] = '1'; } + if(byte_count & 0x01) { binary[byte_count_posn + 8] = '0'; } else { binary[byte_count_posn + 8] = '1'; } +} + +void add_shift_char(char binary[], int shifty) +{ + /* Add a control character to the data stream */ + int i, debug = 0; + int glyph = 0; + + for(i = 0; i < 64; i++) { + if(shift_set[i] == shifty) { + glyph = i; + } + } + + if(debug) { printf("SHIFT [%d] ", glyph); } + + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } +} + +int gm_encode(int gbdata[], int length, char binary[], int reader) +{ + /* Create a binary stream representation of the input data. + 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, + Mixed numerals and latters, Control characters and 8-bit binary data */ + int sp, current_mode, next_mode, last_mode, glyph = 0; + int c1, c2, done; + int p = 0, ppos; + int numbuf[3], punt = 0; + int number_pad_posn, debug = 0; + int byte_count_posn = 0, byte_count = 0; + int shift, i; + + strcpy(binary, ""); + + sp = 0; + current_mode = 0; + last_mode = 0; + number_pad_posn = 0; + + if(reader) { + concat(binary, "1010"); /* FNC3 - Reader Initialisation */ + } + + do { + next_mode = seek_forward(gbdata, length, sp, current_mode); + + if(next_mode != current_mode) { + switch(current_mode) { + case 0: + switch(next_mode) { + case GM_CHINESE: concat(binary, "0001"); break; + case GM_NUMBER: concat(binary, "0010"); break; + case GM_LOWER: concat(binary, "0011"); break; + case GM_UPPER: concat(binary, "0100"); break; + case GM_MIXED: concat(binary, "0101"); break; + case GM_BYTE: concat(binary, "0111"); break; + } + break; + case GM_CHINESE: + switch(next_mode) { + case GM_NUMBER: concat(binary, "1111111100001"); break; // 8161 + case GM_LOWER: concat(binary, "1111111100010"); break; // 8162 + case GM_UPPER: concat(binary, "1111111100011"); break; // 8163 + case GM_MIXED: concat(binary, "1111111100100"); break; // 8164 + case GM_BYTE: concat(binary, "1111111100101"); break; // 8165 + } + break; + case GM_NUMBER: + /* add numeric block padding value */ + switch(p) { + case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit + case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits + } + switch(next_mode) { + case GM_CHINESE: concat(binary, "1111111011"); break; // 1019 + case GM_LOWER: concat(binary, "1111111100"); break; // 1020 + case GM_UPPER: concat(binary, "1111111101"); break; // 1021 + case GM_MIXED: concat(binary, "1111111110"); break; // 1022 + case GM_BYTE: concat(binary, "1111111111"); break; // 1023 + } + break; + case GM_LOWER: + case GM_UPPER: + switch(next_mode) { + case GM_CHINESE: concat(binary, "11100"); break; // 28 + case GM_NUMBER: concat(binary, "11101"); break; // 29 + case GM_LOWER: + case GM_UPPER: concat(binary, "11110"); break; // 30 + case GM_MIXED: concat(binary, "1111100"); break; // 124 + case GM_BYTE: concat(binary, "1111110"); break; // 126 + } + break; + case GM_MIXED: + switch(next_mode) { + case GM_CHINESE: concat(binary, "1111110001"); break; // 1009 + case GM_NUMBER: concat(binary, "1111110010"); break; // 1010 + case GM_LOWER: concat(binary, "1111110011"); break; // 1011 + case GM_UPPER: concat(binary, "1111110100"); break; // 1012 + case GM_BYTE: concat(binary, "1111110111"); break; // 1015 + } + break; + case GM_BYTE: + /* add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + byte_count = 0; + switch(next_mode) { + case GM_CHINESE: concat(binary, "0001"); break; // 1 + case GM_NUMBER: concat(binary, "0010"); break; // 2 + case GM_LOWER: concat(binary, "0011"); break; // 3 + case GM_UPPER: concat(binary, "0100"); break; // 4 + case GM_MIXED: concat(binary, "0101"); break; // 5 + } + break; + } + if(debug) { + switch(next_mode) { + case GM_CHINESE: printf("CHIN "); break; + case GM_NUMBER: printf("NUMB "); break; + case GM_LOWER: printf("LOWR "); break; + case GM_UPPER: printf("UPPR "); break; + case GM_MIXED: printf("MIXD "); break; + case GM_BYTE: printf("BYTE "); break; + } + } + } + last_mode = current_mode; + current_mode = next_mode; + + switch(current_mode) { + case GM_CHINESE: + done = 0; + if(gbdata[sp] > 0xff) { + /* GB2312 character */ + c1 = (gbdata[sp] & 0xff00) >> 8; + c2 = gbdata[sp] & 0xff; + + if((c1 >= 0xa0) && (c1 <= 0xa9)) { + glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0); + } + if((c1 >= 0xb0) && (c1 <= 0xf7)) { + glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0); + } + done = 1; + } + if(!(done)) { + if(sp != (length - 1)) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* End of Line */ + glyph = 7776; + sp++; + } + done = 1; + } + } + if(!(done)) { + if(sp != (length - 1)) { + if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && + ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + /* Two digits */ + glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0'); + sp++; + } + } + } + if(!(done)) { + /* Byte value */ + glyph = 7777 + gbdata[sp]; + } + + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + sp++; + break; + + case GM_NUMBER: + if(last_mode != current_mode) { + /* Reserve a space for numeric digit padding value (2 bits) */ + number_pad_posn = strlen(binary); + concat(binary, "XX"); + } + p = 0; + ppos = -1; + + /* Numeric compression can also include certain combinations of + non-numeric character */ + + numbuf[0] = '0'; + numbuf[1] = '0'; + numbuf[2] = '0'; + do { + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + numbuf[p] = gbdata[sp]; + sp++; + p++; + } + switch(gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + punt = gbdata[sp]; + sp++; + ppos = p; + break; + } + if(sp < (length - 1)) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* */ + punt = gbdata[sp]; + sp += 2; + ppos = p; + } + } + } while ((p < 3) && (sp < length)); + + if(ppos != -1) { + switch(punt) { + case ' ': glyph = 0; break; + case '+': glyph = 3; break; + case '-': glyph = 6; break; + case '.': glyph = 9; break; + case ',': glyph = 12; break; + case 0x13: glyph = 15; break; + } + glyph += ppos; + glyph += 1000; + + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } + + glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0'); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + + case GM_BYTE: + if(last_mode != current_mode) { + /* Reserve space for byte block length indicator (9 bits) */ + byte_count_posn = strlen(binary); + concat(binary, "LLLLLLLLL"); + } + if(byte_count == 512) { + /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */ + add_byte_count(binary, byte_count_posn, byte_count); + concat(binary, "0111"); + byte_count_posn = strlen(binary); + concat(binary, "LLLLLLLLL"); + byte_count = 0; + } + + glyph = gbdata[sp]; + if(debug) { printf("[%d] ", glyph); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + sp++; + byte_count++; + break; + + case GM_MIXED: + shift = 1; + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { shift = 0; } + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Mixed Mode character */ + glyph = posn(EUROPIUM, gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111110110"); /* 1014 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_UPPER: + shift = 1; + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Upper Case character */ + glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111101"); /* 127 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_LOWER: + shift = 1; + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Lower Case character */ + glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111101"); /* 127 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + } + if(strlen(binary) > 9191) { + return ERROR_TOO_LONG; + } + + } while(sp < length); + + if(current_mode == GM_NUMBER) { + /* add numeric block padding value */ + switch(p) { + case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit + case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits + } + } + + if(current_mode == GM_BYTE) { + /* Add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + } + + /* Add "end of data" character */ + switch(current_mode) { + case GM_CHINESE: concat(binary, "1111111100000"); break; // 8160 + case GM_NUMBER: concat(binary, "1111111010"); break; // 1018 + case GM_LOWER: + case GM_UPPER: concat(binary, "11011"); break; // 27 + case GM_MIXED: concat(binary, "1111110000"); break; // 1008 + case GM_BYTE: concat(binary, "0000"); break; // 0 + } + + /* Add padding bits if required */ + p = 7 - (strlen(binary) % 7); + if(p == 7) { p = 0; } + for(i = 0; i < p; i++) { + concat(binary, "0"); + } + + if(strlen(binary) > 9191) { + return ERROR_TOO_LONG; + } + return 0; +} + +void gm_add_ecc(char binary[], int data_posn, int layers, int ecc_level, int word[]) +{ + int total_cw, data_cw, i, j, wp; + int n1, b1, n2, b2, e1, b3, e2; + int block_size, data_size, ecc_size, toggle; + int data[1320], block[130]; + unsigned char data_block[115], ecc_block[70]; + + total_cw = gm_total_cw[(layers - 1)]; + data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)]; + + for(i = 0; i < 1320; i++) { + data[i] = 0; + } + + /* Convert from binary sream to 7-bit codewords */ + for(i = 0; i < data_posn; i++) { + if(binary[i * 7] == '1') { data[i] += 0x40; } + if(binary[(i * 7) + 1] == '1') { data[i] += 0x20; } + if(binary[(i * 7) + 2] == '1') { data[i] += 0x10; } + if(binary[(i * 7) + 3] == '1') { data[i] += 0x08; } + if(binary[(i * 7) + 4] == '1') { data[i] += 0x04; } + if(binary[(i * 7) + 5] == '1') { data[i] += 0x02; } + if(binary[(i * 7) + 6] == '1') { data[i] += 0x01; } + } + + /* Add padding codewords */ + data[data_posn] = 0x00; + for(i = (data_posn + 1); i < data_cw; i++) { + if(i % 2) { + data[i] = 0x7e; + toggle = 1; + } else { + data[i] = 0x00; + toggle = 0; + } + } + + /* Get block sizes */ + n1 = gm_n1[(layers - 1)]; + b1 = gm_b1[(layers - 1)]; + n2 = n1 - 1; + b2 = gm_b2[(layers - 1)]; + e1 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4)]; + b3 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 1]; + e2 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 2]; + + /* Split the data into blocks */ + wp = 0; + for(i = 0; i < (b1 + b2); i++) { + if(i < b1) { block_size = n1; } else { block_size = n2; } + if(i < b3) { ecc_size = e1; } else { ecc_size = e2; } + data_size = block_size - ecc_size; + + /* printf("block %d/%d: data %d / ecc %d\n", i + 1, (b1 + b2), data_size, ecc_size);*/ + + for(j = 0; j < data_size; j++) { + data_block[j] = data[wp]; + wp++; + } + + /* Calculate ECC data for this block */ + rs_init_gf(0x89); + rs_init_code(ecc_size, 1); + rs_encode(data_size, data_block, ecc_block); + rs_free(); + + /* Correct error correction data but in reverse order */ + for(j = 0; j < data_size; j++) { + block[j] = data_block[j]; + } + for(j = 0; j < ecc_size; j++) { + block[(j + data_size)] = ecc_block[ecc_size - j - 1]; + } + + for(j = 0; j < n2; j++) { + word[((b1 + b2) * j) + i] = block[j]; + } + if(block_size == n1) { + word[((b1 + b2) * (n1 - 1)) + i] = block[(n1 - 1)]; + } + } +} + +void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) +{ + int i, j; + + i = (x * 6) + 1; + j = (y * 6) + 1; + + if(word2 & 0x40) { grid[(j * size) + i + 2] = '1'; } + if(word2 & 0x20) { grid[(j * size) + i + 3] = '1'; } + if(word2 & 0x10) { grid[((j + 1) * size) + i] = '1'; } + if(word2 & 0x08) { grid[((j + 1) * size) + i + 1] = '1'; } + if(word2 & 0x04) { grid[((j + 1) * size) + i + 2] = '1'; } + if(word2 & 0x02) { grid[((j + 1) * size) + i + 3] = '1'; } + if(word2 & 0x01) { grid[((j + 2) * size) + i] = '1'; } + if(word1 & 0x40) { grid[((j + 2) * size) + i + 1] = '1'; } + if(word1 & 0x20) { grid[((j + 2) * size) + i + 2] = '1'; } + if(word1 & 0x10) { grid[((j + 2) * size) + i + 3] = '1'; } + if(word1 & 0x08) { grid[((j + 3) * size) + i] = '1'; } + if(word1 & 0x04) { grid[((j + 3) * size) + i + 1] = '1'; } + if(word1 & 0x02) { grid[((j + 3) * size) + i + 2] = '1'; } + if(word1 & 0x01) { grid[((j + 3) * size) + i + 3] = '1'; } +} + +void place_data_in_grid(int word[], char grid[], int modules, int size) +{ + int x, y, macromodule, offset; + + offset = 13 - ((modules - 1) / 2); + for(y = 0; y < modules; y++) { + for(x = 0; x < modules; x++) { + macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; + place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); + } + } +} + +void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level) +{ + /* Place the layer ID into each macromodule */ + + int i, j, layer, start, stop; + +#ifndef _MSC_VER + int layerid[layers + 1]; + int id[modules * modules]; +#else + int* layerid = (int *)_alloca((layers + 1) * sizeof(int)); + int* id = (int *)_alloca((modules * modules) * sizeof(int)); +#endif + + /* Calculate Layer IDs */ + for(i = 0; i <= layers; i++) { + if(ecc_level == 1) { + layerid[i] = 3 - (i % 4); + } else { + layerid[i] = (i + 5 - ecc_level) % 4; + } + } + + for(i = 0; i < modules; i++) { + for(j = 0; j < modules; j++) { + id[(i * modules) + j] = 0; + } + } + + /* Calculate which value goes in each macromodule */ + start = modules / 2; + stop = modules / 2; + for(layer = 0; layer <= layers; layer++) { + for(i = start; i <= stop; i++) { + id[(start * modules) + i] = layerid[layer]; + id[(i * modules) + start] = layerid[layer]; + id[((modules - start - 1) * modules) + i] = layerid[layer]; + id[(i * modules) + (modules - start - 1)] = layerid[layer]; + } + start--; + stop++; + } + + /* Place the data in the grid */ + for(i = 0; i < modules; i++) { + for(j = 0; j < modules; j++) { + if(id[(i * modules) + j] & 0x02) { + grid[(((i * 6) + 1) * size) + (j * 6) + 1] = '1'; + } + if(id[(i * modules) + j] & 0x01) { + grid[(((i * 6) + 1) * size) + (j * 6) + 2] = '1'; + } + } + } +} + +int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int size, modules, dark, error_number; + int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; + int x, y, i, j, glyph; + char binary[9300]; + int data_cw, input_latch = 0; + int word[1460], data_max, reader = 0; + +#ifndef _MSC_VER + int utfdata[length + 1]; + int gbdata[length + 1]; +#else + int* utfdata = (int *)_alloca((length + 1) * sizeof(int)); + int* gbdata = (int *)_alloca((length + 1) * sizeof(int)); +#endif + + for(i = 0; i < 1460; i++) { + word[i] = 0; + } + + switch(symbol->input_mode) { + case DATA_MODE: + for(i = 0; i < length; i++) { + gbdata[i] = (int)source[i]; + } + break; + default: + /* Convert Unicode input to GB-2312 */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if(error_number != 0) { return error_number; } + + for(i = 0; i < length; i++) { + if(utfdata[i] <= 0xff) { + gbdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if(gb2312_lookup[j * 2] == utfdata[i]) { + glyph = gb2312_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 7445) && (glyph == 0)); + if(glyph == 0) { + strcpy(symbol->errtxt, "Invalid character in input data"); + return ERROR_INVALID_DATA; + } + gbdata[i] = glyph; + } + } + break; + } + + if(symbol->output_options & READER_INIT) reader = 1; + + error_number = gm_encode(gbdata, length, binary, reader); + if(error_number != 0) { + strcpy(symbol->errtxt, "Input data too long"); + return error_number; + } + + /* Determine the size of the symbol */ + data_cw = strlen(binary) / 7; + + auto_layers = 13; + for(i = 12; i > 0; i--) { + if(gm_recommend_cw[(i - 1)] >= data_cw) { auto_layers = i; } + } + min_layers = 13; + for(i = 12; i > 0; i--) { + if(gm_max_cw[(i - 1)] >= data_cw) { min_layers = i; } + } + layers = auto_layers; + auto_ecc_level = 3; + if(layers == 1) { auto_ecc_level = 5; } + if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } + min_ecc_level = 1; + if(layers == 1) { min_ecc_level = 4; } + if((layers == 2) || (layers == 3)) { min_ecc_level = 2; } + ecc_level = auto_ecc_level; + + if((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) { + input_latch = 1; + if(symbol->option_2 > min_layers) { + layers = symbol->option_2; + } else { + layers = min_layers; + } + } + + if(input_latch == 1) { + auto_ecc_level = 3; + if(layers == 1) { auto_ecc_level = 5; } + if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } + ecc_level = auto_ecc_level; + if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + layers++; + } + } + + if(input_latch == 0) { + if((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) { + if(symbol->option_1 > min_ecc_level) { + ecc_level = symbol->option_1; + } else { + ecc_level = min_ecc_level; + } + } + if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + do { + layers++; + } while ((data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) && (layers <= 13)); + } + } + + data_max = 1313; + switch(ecc_level) { + case 2: data_max = 1167; break; + case 3: data_max = 1021; break; + case 4: data_max = 875; break; + case 5: data_max = 729; break; + } + + if(data_cw > data_max) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + + gm_add_ecc(binary, data_cw, layers, ecc_level, word); + size = 6 + (layers * 12); + modules = 1 + (layers * 2); + +#ifndef _MSC_VER + char grid[size * size]; +#else + char* grid = (char *)_alloca((size * size) * sizeof(char)); +#endif + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + grid[(y * size) + x] = '0'; + } + } + + place_data_in_grid(word, grid, modules, size); + place_layer_id(grid, size, layers, modules, ecc_level); + + /* Add macromodule frames */ + for(x = 0; x < modules; x++) { + dark = 1 - (x % 2); + for(y = 0; y < modules; y++) { + if(dark == 1) { + for(i = 0; i < 5; i++) { + grid[((y * 6) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + 5) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + i) * size) + (x * 6)] = '1'; + grid[(((y * 6) + i) * size) + (x * 6) + 5] = '1'; + } + grid[(((y * 6) + 5) * size) + (x * 6) + 5] = '1'; + dark = 0; + } else { + dark = 1; + } + } + } + + /* Copy values to symbol */ + symbol->width = size; + symbol->rows = size; + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + if(grid[(y * size) + x] == '1') { + set_module(symbol, y, x); + } + } + symbol->row_height[x] = 1; + } + + return 0; +} diff --git a/backend/gridmtx.h b/backend/gridmtx.h new file mode 100644 index 00000000..ba684a1d --- /dev/null +++ b/backend/gridmtx.h @@ -0,0 +1,160 @@ +/* gridmtx.h - definitions for Grid Matrix + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +#define GM_NUMBER 1 +#define GM_LOWER 2 +#define GM_UPPER 3 +#define GM_MIXED 4 +#define GM_CONTROL 5 +#define GM_BYTE 6 +#define GM_CHINESE 7 + +#define EUROPIUM "0123456789ABCDEFGHIJKLMOPRSTUVWXYZabcdefghijklmnopqrstuvwxyz " + +static char shift_set[] = { + /* From Table 7 - Encoding of control characters */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* NULL -> SI */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* DLE -> US */ + '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', + ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' +}; + +static int gm_recommend_cw[] = { 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 }; +static int gm_max_cw[] = { 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 }; +static int gm_total_cw[] = { 18, 50, 98, 162, 242, 338, 450, 578, 722, 882, 1058, 1250, 1458 }; + +static int gm_data_codewords[] = { + 0, 15, 13, 11, 9, + 45, 40, 35, 30, 25, + 89, 79, 69, 59, 49, + 146, 130, 114, 98, 81, + 218, 194, 170, 146, 121, + 305, 271, 237, 203, 169, + 405, 360, 315, 270, 225, + 521, 463, 405, 347, 289, + 650, 578, 506, 434, 361, + 794, 706, 618, 530, 441, + 953, 847, 741, 635, 529, + 1125, 1000, 875, 750, 625, + 1313, 1167, 1021, 875, 729 +}; + +static int gm_n1[] = { 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122 }; +static int gm_b1[] = { 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6 }; +static int gm_b2[] = { 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6 }; + +static int gm_ebeb[] = { + /* E1 B3 E2 B4 */ + 0, 0, 0, 0, // version 1 + 3, 1, 0, 0, + 5, 1, 0, 0, + 7, 1, 0, 0, + 9, 1, 0, 0, + 5, 1, 0, 0, // version 2 + 10, 1, 0, 0, + 15, 1, 0, 0, + 20, 1, 0, 0, + 25, 1, 0, 0, + 9, 1, 0, 0, // version 3 + 19, 1, 0, 0, + 29, 1, 0, 0, + 39, 1, 0, 0, + 49, 1, 0, 0, + 8, 2, 0, 0, // version 4 + 16, 2, 0, 0, + 24, 2, 0, 0, + 32, 2, 0, 0, + 41, 1, 10, 1, + 12, 2, 0, 0, // version 5 + 24, 2, 0, 0, + 36, 2, 0, 0, + 48, 2, 0, 0, + 61, 1, 60, 1, + 11, 3, 0, 0, // version 6 + 23, 1, 22, 2, + 34, 2, 33, 1, + 45, 3, 0, 0, + 57, 1, 56, 2, + 12, 1, 11, 3, // version 7 + 23, 2, 22, 2, + 34, 3, 33, 1, + 45, 4, 0, 0, + 57, 1, 56, 3, + 12, 2, 11, 3, // version 8 + 23, 5, 0, 0, + 35, 3, 34, 2, + 47, 1, 46, 4, + 58, 4, 57, 1, + 12, 6, 0, 0, // version 9 + 24, 6, 0, 0, + 36, 6, 0, 0, + 48, 6, 0, 0, + 61, 1, 60, 5, + 13, 4, 12, 3, // version 10 + 26, 1, 25, 6, + 38, 5, 37, 2, + 51, 2, 50, 5, + 63, 7, 0, 0, + 12, 6, 11, 3, // version 11 + 24, 4, 23, 5, + 36, 2, 35, 7, + 47, 9, 0, 0, + 59, 7, 58, 2, + 13, 5, 12, 5, // version 12 + 25, 10, 0, 0, + 38, 5, 37, 5, + 50, 10, 0, 0, + 63, 5, 62, 5, + 13, 1, 12, 11, //version 13 + 25, 3, 24, 9, + 37, 5, 36, 7, + 49, 7, 48, 5, + 61, 9, 60, 3 +}; + +static int gm_macro_matrix[] = { + 728,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650, + 727,624,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,651, + 726,623,528,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,553,652, + 725,622,527,440,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,463,554,653, + 724,621,526,439,360,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,381,464,555,654, + 723,620,525,438,359,288,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,307,382,465,556,655, + 722,619,524,437,358,287,224,169,170,171,172,173,174,175,176,177,178,179,180,181,182,241,308,383,466,557,656, + 721,618,523,436,357,286,223,168,121,122,123,124,125,126,127,128,129,130,131,132,183,242,309,384,467,558,657, + 720,617,522,435,356,285,222,167,120,81,82,83,84,85,86,87,88,89,90,133,184,243,310,385,468,559,658, + 719,616,521,434,355,284,221,166,119,80,49,50,51,52,53,54,55,56,91,134,185,244,311,386,469,560,659, + 718,615,520,433,354,283,220,165,118,79,48,25,26,27,28,29,30,57,92,135,186,245,312,387,470,561,660, + 717,614,519,432,353,282,219,164,117,78,47,24,9,10,11,12,31,58,93,136,187,246,313,388,471,562,661, + 716,613,518,431,352,281,218,163,116,77,46,23,8,1,2,13,32,59,94,137,188,247,314,389,472,563,662, + 715,612,517,430,351,280,217,162,115,76,45,22,7,0,3,14,33,60,95,138,189,248,315,390,473,564,663, + 714,611,516,429,350,279,216,161,114,75,44,21,6,5,4,15,34,61,96,139,190,249,316,391,474,565,664, + 713,610,515,428,349,278,215,160,113,74,43,20,19,18,17,16,35,62,97,140,191,250,317,392,475,566,665, + 712,609,514,427,348,277,214,159,112,73,42,41,40,39,38,37,36,63,98,141,192,251,318,393,476,567,666, + 711,608,513,426,347,276,213,158,111,72,71,70,69,68,67,66,65,64,99,142,193,252,319,394,477,568,667, + 710,607,512,425,346,275,212,157,110,109,108,107,106,105,104,103,102,101,100,143,194,253,320,395,478,569,668, + 709,606,511,424,345,274,211,156,155,154,153,152,151,150,149,148,147,146,145,144,195,254,321,396,479,570,669, + 708,605,510,423,344,273,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,255,322,397,480,571,670, + 707,604,509,422,343,272,271,270,269,268,267,266,265,264,263,262,261,260,259,258,257,256,323,398,481,572,671, + 706,603,508,421,342,341,340,339,338,337,336,335,334,333,332,331,330,329,328,327,326,325,324,399,482,573,672, + 705,602,507,420,419,418,417,416,415,414,413,412,411,410,409,408,407,406,405,404,403,402,401,400,483,574,673, + 704,601,506,505,504,503,502,501,500,499,498,497,496,495,494,493,492,491,490,489,488,487,486,485,484,575,674, + 703,600,599,598,597,596,595,594,593,592,591,590,589,588,587,586,585,584,583,582,581,580,579,578,577,576,675, + 702,701,700,699,698,697,696,695,694,693,692,691,690,689,688,687,686,685,684,683,682,681,680,679,678,677,676, +}; diff --git a/backend/gs1.c b/backend/gs1.c new file mode 100644 index 00000000..e567b5f1 --- /dev/null +++ b/backend/gs1.c @@ -0,0 +1,287 @@ +/* gs1.c - Verifies GS1 data */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +/* This code does some checks on the integrity of GS1 data. It is not intended + to be bulletproof, nor does it report very accurately what problem was found + or where, but should prevent some of the more common encoding errors */ + +void itostr(char ai_string[], int ai_value) +{ + int thou, hund, ten, unit; + char temp[2]; + + strcpy(ai_string, "("); + thou = ai_value / 1000; + hund = (ai_value - (1000 * thou)) / 100; + ten = (ai_value - ((1000 * thou) + (100 * hund))) / 10; + unit = ai_value - ((1000 * thou) + (100 * hund) + (10 * ten)); + + temp[1] = '\0'; + if(ai_value >= 1000) { temp[0] = itoc(thou); concat(ai_string, temp); } + if(ai_value >= 100) { temp[0] = itoc(hund); concat(ai_string, temp); } + temp[0] = itoc(ten); + concat(ai_string, temp); + temp[0] = itoc(unit); + concat(ai_string, temp); + concat(ai_string, ")"); +} + +int gs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char reduced[]) +{ + int i, j, last_ai, ai_latch; + char ai_string[6]; + int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length; + int ai_value[100], ai_location[100], ai_count, data_location[100], data_length[100]; + int error_latch; + + /* Detect extended ASCII characters */ + for(i = 0; i < src_len; i++) { + if(source[i] >=128) { + strcpy(symbol->errtxt, "Extended ASCII characters are not supported by GS1"); + return ERROR_INVALID_DATA; + } + if(source[i] < 32) { + strcpy(symbol->errtxt, "Control characters are not supported by GS1"); + return ERROR_INVALID_DATA; + } + } + + if(source[0] != '[') { + strcpy(symbol->errtxt, "Data does not start with an AI"); + return ERROR_INVALID_DATA; + } + + /* Check the position of the brackets */ + bracket_level = 0; + max_bracket_level = 0; + ai_length = 0; + max_ai_length = 0; + min_ai_length = 5; + j = 0; + ai_latch = 0; + for(i = 0; i < src_len; i++) { + ai_length += j; + if(((j == 1) && (source[i] != ']')) && ((source[i] < '0') || (source[i] > '9'))) { ai_latch = 1; } + if(source[i] == '[') { bracket_level++; j = 1; } + if(source[i] == ']') { + bracket_level--; + if(ai_length < min_ai_length) { min_ai_length = ai_length; } + j = 0; + ai_length = 0; + } + if(bracket_level > max_bracket_level) { max_bracket_level = bracket_level; } + if(ai_length > max_ai_length) { max_ai_length = ai_length; } + } + min_ai_length--; + + if(bracket_level != 0) { + /* Not all brackets are closed */ + strcpy(symbol->errtxt, "Malformed AI in input data (brackets don\'t match)"); + return ERROR_INVALID_DATA; + } + + if(max_bracket_level > 1) { + /* Nested brackets */ + strcpy(symbol->errtxt, "Found nested brackets in input data"); + return ERROR_INVALID_DATA; + } + + if(max_ai_length > 4) { + /* AI is too long */ + strcpy(symbol->errtxt, "Invalid AI in input data (AI too long)"); + return ERROR_INVALID_DATA; + } + + if(min_ai_length <= 1) { + /* AI is too short */ + strcpy(symbol->errtxt, "Invalid AI in input data (AI too short)"); + return ERROR_INVALID_DATA; + } + + if(ai_latch == 1) { + /* Non-numeric data in AI */ + strcpy(symbol->errtxt, "Invalid AI in input data (non-numeric characters in AI)"); + return ERROR_INVALID_DATA; + } + + ai_count = 0; + for(i = 1; i < src_len; i++) { + if(source[i - 1] == '[') { + ai_location[ai_count] = i; + j = 0; + do { + ai_string[j] = source[i + j]; + j++; + } while (ai_string[j - 1] != ']'); + ai_string[j - 1] = '\0'; + ai_value[ai_count] = atoi(ai_string); + ai_count++; + } + } + + for(i = 0; i < ai_count; i++) { + data_location[i] = ai_location[i] + 3; + if(ai_value[i] >= 100) { data_location[i]++; } + if(ai_value[i] >= 1000) { data_location[i]++; } + data_length[i] = 0; + do { + data_length[i]++; + } while ((source[data_location[i] + data_length[i] - 1] != '[') && (source[data_location[i] + data_length[i] - 1] != '\0')); + data_length[i]--; + } + + for(i = 0; i < ai_count; i++) { + if(data_length[i] == 0) { + /* No data for given AI */ + strcpy(symbol->errtxt, "Empty data field in input data"); + return ERROR_INVALID_DATA; + } + } + + error_latch = 0; + strcpy(ai_string, ""); + for(i = 0; i < ai_count; i++) { + switch (ai_value[i]) { + case 0: if(data_length[i] != 18) { error_latch = 1; } break; + case 1: if(data_length[i] != 14) { error_latch = 1; } break; + case 2: if(data_length[i] != 14) { error_latch = 1; } break; + case 3: if(data_length[i] != 14) { error_latch = 1; } break; + case 4: if(data_length[i] != 16) { error_latch = 1; } break; + case 11: if(data_length[i] != 6) { error_latch = 1; } break; + case 12: if(data_length[i] != 6) { error_latch = 1; } break; + case 13: if(data_length[i] != 6) { error_latch = 1; } break; + case 14: if(data_length[i] != 6) { error_latch = 1; } break; + case 15: if(data_length[i] != 6) { error_latch = 1; } break; + case 16: if(data_length[i] != 6) { error_latch = 1; } break; + case 17: if(data_length[i] != 6) { error_latch = 1; } break; + case 18: if(data_length[i] != 6) { error_latch = 1; } break; + case 19: if(data_length[i] != 6) { error_latch = 1; } break; + case 20: if(data_length[i] != 2) { error_latch = 1; } break; + case 23: error_latch = 2; break; + case 24: error_latch = 2; break; + case 25: error_latch = 2; break; + case 39: error_latch = 2; break; + case 40: error_latch = 2; break; + case 41: error_latch = 2; break; + case 42: error_latch = 2; break; + case 70: error_latch = 2; break; + case 80: error_latch = 2; break; + case 81: error_latch = 2; break; + } + if((ai_value[i] >= 100) && (ai_value[i] <= 179)) { error_latch = 2; } + if((ai_value[i] >= 1000) && (ai_value[i] <= 1799)) { error_latch = 2; } + if((ai_value[i] >= 200) && (ai_value[i] <= 229)) { error_latch = 2; } + if((ai_value[i] >= 2000) && (ai_value[i] <= 2299)) { error_latch = 2; } + if((ai_value[i] >= 300) && (ai_value[i] <= 309)) { error_latch = 2; } + if((ai_value[i] >= 3000) && (ai_value[i] <= 3099)) { error_latch = 2; } + if((ai_value[i] >= 31) && (ai_value[i] <= 36)) { error_latch = 2; } + if((ai_value[i] >= 310) && (ai_value[i] <= 369)) { error_latch = 2; } + if((ai_value[i] >= 3100) && (ai_value[i] <= 3699)) { if(data_length[i] != 6) { error_latch = 1; } } + if((ai_value[i] >= 370) && (ai_value[i] <= 379)) { error_latch = 2; } + if((ai_value[i] >= 3700) && (ai_value[i] <= 3799)) { error_latch = 2; } + if((ai_value[i] >= 410) && (ai_value[i] <= 415)) { if(data_length[i] != 13) { error_latch = 1; } } + if((ai_value[i] >= 4100) && (ai_value[i] <= 4199)) { error_latch = 2; } + if((ai_value[i] >= 700) && (ai_value[i] <= 703)) { error_latch = 2; } + if((ai_value[i] >= 800) && (ai_value[i] <= 810)) { error_latch = 2; } + if((ai_value[i] >= 900) && (ai_value[i] <= 999)) { error_latch = 2; } + if((ai_value[i] >= 9000) && (ai_value[i] <= 9999)) { error_latch = 2; } + if((error_latch < 4) && (error_latch > 0)) { + /* error has just been detected: capture AI */ + itostr(ai_string, ai_value[i]); + error_latch += 4; + } + } + + if(error_latch == 5) { + strcpy(symbol->errtxt, "Invalid data length for AI "); + concat(symbol->errtxt, ai_string); + return ERROR_INVALID_DATA; + } + + if(error_latch == 6) { + strcpy(symbol->errtxt, "Invalid AI value "); + concat(symbol->errtxt, ai_string); + return ERROR_INVALID_DATA; + } + + /* Resolve AI data - put resulting string in 'reduced' */ + j = 0; + last_ai = 0; + ai_latch = 1; + for(i = 0; i < src_len; i++) { + if((source[i] != '[') && (source[i] != ']')) { + reduced[j++] = source[i]; + } + if(source[i] == '[') { + /* Start of an AI string */ + if(ai_latch == 0) { + reduced[j++] = '['; + } + ai_string[0] = source[i + 1]; + ai_string[1] = source[i + 2]; + ai_string[2] = '\0'; + last_ai = atoi(ai_string); + ai_latch = 0; + /* The following values from "GS-1 General Specification version 8.0 issue 2, May 2008" + figure 5.4.8.2.1 - 1 "Element Strings with Pre-Defined Length Using Application Identifiers" */ + if((last_ai >= 0) && (last_ai <= 4)) { ai_latch = 1; } + if((last_ai >= 11) && (last_ai <= 20)) { ai_latch = 1; } + if(last_ai == 23) { ai_latch = 1; } /* legacy support - see 5.3.8.2.2 */ + if((last_ai >= 31) && (last_ai <= 36)) { ai_latch = 1; } + if(last_ai == 41) { ai_latch = 1; } + } + /* The ']' character is simply dropped from the input */ + } + reduced[j] = '\0'; + + /* the character '[' in the reduced string refers to the FNC1 character */ + return 0; +} + +int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[]) +{ + /* Only to keep the compiler happy */ +#ifndef _MSC_VER + char temp[src_len + 5]; +#else + char* temp = (char*)_alloca(src_len + 5); +#endif + int error_number; + + error_number = gs1_verify(symbol, source, src_len, temp); + if(error_number != 0) { return error_number; } + + if (strlen(temp) < src_len + 5) { + ustrcpy(reduced, (unsigned char*)temp); + return 0; + } + strcpy(symbol->errtxt, "ugs1_verify overflow"); + return ERROR_INVALID_DATA; +} diff --git a/backend/gs1.h b/backend/gs1.h new file mode 100644 index 00000000..42b40df7 --- /dev/null +++ b/backend/gs1.h @@ -0,0 +1,35 @@ +/* gs1.h - Verifies GS1 data */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ +#ifndef __GS1_H +#define __GS1_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern int gs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char reduced[]); +extern int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GS1_H */ \ No newline at end of file diff --git a/backend/imail.c b/backend/imail.c new file mode 100644 index 00000000..fc9c82eb --- /dev/null +++ b/backend/imail.c @@ -0,0 +1,700 @@ +/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence" + is Copyright (C) 2006 United States Postal Service */ + +static short int BCD[40] = { + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 0, 0, + 1, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 0, + 0, 0, 0, 1, + 1, 0, 0, 1 +}; + +#include +#include +#include +#include "common.h" +#include "large.h" + +#define SODIUM "0123456789-" + +/* The following lookup tables were generated using the code in Appendix C */ + +static unsigned short AppxD_I[1287] = { /* Appendix D Table 1 - 5 of 13 characters */ + 0x001F, 0x1F00, 0x002F, 0x1E80, 0x0037, 0x1D80, 0x003B, 0x1B80, 0x003D, 0x1780, + 0x003E, 0x0F80, 0x004F, 0x1E40, 0x0057, 0x1D40, 0x005B, 0x1B40, 0x005D, 0x1740, + 0x005E, 0x0F40, 0x0067, 0x1CC0, 0x006B, 0x1AC0, 0x006D, 0x16C0, 0x006E, 0x0EC0, + 0x0073, 0x19C0, 0x0075, 0x15C0, 0x0076, 0x0DC0, 0x0079, 0x13C0, 0x007A, 0x0BC0, + 0x007C, 0x07C0, 0x008F, 0x1E20, 0x0097, 0x1D20, 0x009B, 0x1B20, 0x009D, 0x1720, + 0x009E, 0x0F20, 0x00A7, 0x1CA0, 0x00AB, 0x1AA0, 0x00AD, 0x16A0, 0x00AE, 0x0EA0, + 0x00B3, 0x19A0, 0x00B5, 0x15A0, 0x00B6, 0x0DA0, 0x00B9, 0x13A0, 0x00BA, 0x0BA0, + 0x00BC, 0x07A0, 0x00C7, 0x1C60, 0x00CB, 0x1A60, 0x00CD, 0x1660, 0x00CE, 0x0E60, + 0x00D3, 0x1960, 0x00D5, 0x1560, 0x00D6, 0x0D60, 0x00D9, 0x1360, 0x00DA, 0x0B60, + 0x00DC, 0x0760, 0x00E3, 0x18E0, 0x00E5, 0x14E0, 0x00E6, 0x0CE0, 0x00E9, 0x12E0, + 0x00EA, 0x0AE0, 0x00EC, 0x06E0, 0x00F1, 0x11E0, 0x00F2, 0x09E0, 0x00F4, 0x05E0, + 0x00F8, 0x03E0, 0x010F, 0x1E10, 0x0117, 0x1D10, 0x011B, 0x1B10, 0x011D, 0x1710, + 0x011E, 0x0F10, 0x0127, 0x1C90, 0x012B, 0x1A90, 0x012D, 0x1690, 0x012E, 0x0E90, + 0x0133, 0x1990, 0x0135, 0x1590, 0x0136, 0x0D90, 0x0139, 0x1390, 0x013A, 0x0B90, + 0x013C, 0x0790, 0x0147, 0x1C50, 0x014B, 0x1A50, 0x014D, 0x1650, 0x014E, 0x0E50, + 0x0153, 0x1950, 0x0155, 0x1550, 0x0156, 0x0D50, 0x0159, 0x1350, 0x015A, 0x0B50, + 0x015C, 0x0750, 0x0163, 0x18D0, 0x0165, 0x14D0, 0x0166, 0x0CD0, 0x0169, 0x12D0, + 0x016A, 0x0AD0, 0x016C, 0x06D0, 0x0171, 0x11D0, 0x0172, 0x09D0, 0x0174, 0x05D0, + 0x0178, 0x03D0, 0x0187, 0x1C30, 0x018B, 0x1A30, 0x018D, 0x1630, 0x018E, 0x0E30, + 0x0193, 0x1930, 0x0195, 0x1530, 0x0196, 0x0D30, 0x0199, 0x1330, 0x019A, 0x0B30, + 0x019C, 0x0730, 0x01A3, 0x18B0, 0x01A5, 0x14B0, 0x01A6, 0x0CB0, 0x01A9, 0x12B0, + 0x01AA, 0x0AB0, 0x01AC, 0x06B0, 0x01B1, 0x11B0, 0x01B2, 0x09B0, 0x01B4, 0x05B0, + 0x01B8, 0x03B0, 0x01C3, 0x1870, 0x01C5, 0x1470, 0x01C6, 0x0C70, 0x01C9, 0x1270, + 0x01CA, 0x0A70, 0x01CC, 0x0670, 0x01D1, 0x1170, 0x01D2, 0x0970, 0x01D4, 0x0570, + 0x01D8, 0x0370, 0x01E1, 0x10F0, 0x01E2, 0x08F0, 0x01E4, 0x04F0, 0x01E8, 0x02F0, + 0x020F, 0x1E08, 0x0217, 0x1D08, 0x021B, 0x1B08, 0x021D, 0x1708, 0x021E, 0x0F08, + 0x0227, 0x1C88, 0x022B, 0x1A88, 0x022D, 0x1688, 0x022E, 0x0E88, 0x0233, 0x1988, + 0x0235, 0x1588, 0x0236, 0x0D88, 0x0239, 0x1388, 0x023A, 0x0B88, 0x023C, 0x0788, + 0x0247, 0x1C48, 0x024B, 0x1A48, 0x024D, 0x1648, 0x024E, 0x0E48, 0x0253, 0x1948, + 0x0255, 0x1548, 0x0256, 0x0D48, 0x0259, 0x1348, 0x025A, 0x0B48, 0x025C, 0x0748, + 0x0263, 0x18C8, 0x0265, 0x14C8, 0x0266, 0x0CC8, 0x0269, 0x12C8, 0x026A, 0x0AC8, + 0x026C, 0x06C8, 0x0271, 0x11C8, 0x0272, 0x09C8, 0x0274, 0x05C8, 0x0278, 0x03C8, + 0x0287, 0x1C28, 0x028B, 0x1A28, 0x028D, 0x1628, 0x028E, 0x0E28, 0x0293, 0x1928, + 0x0295, 0x1528, 0x0296, 0x0D28, 0x0299, 0x1328, 0x029A, 0x0B28, 0x029C, 0x0728, + 0x02A3, 0x18A8, 0x02A5, 0x14A8, 0x02A6, 0x0CA8, 0x02A9, 0x12A8, 0x02AA, 0x0AA8, + 0x02AC, 0x06A8, 0x02B1, 0x11A8, 0x02B2, 0x09A8, 0x02B4, 0x05A8, 0x02B8, 0x03A8, + 0x02C3, 0x1868, 0x02C5, 0x1468, 0x02C6, 0x0C68, 0x02C9, 0x1268, 0x02CA, 0x0A68, + 0x02CC, 0x0668, 0x02D1, 0x1168, 0x02D2, 0x0968, 0x02D4, 0x0568, 0x02D8, 0x0368, + 0x02E1, 0x10E8, 0x02E2, 0x08E8, 0x02E4, 0x04E8, 0x0307, 0x1C18, 0x030B, 0x1A18, + 0x030D, 0x1618, 0x030E, 0x0E18, 0x0313, 0x1918, 0x0315, 0x1518, 0x0316, 0x0D18, + 0x0319, 0x1318, 0x031A, 0x0B18, 0x031C, 0x0718, 0x0323, 0x1898, 0x0325, 0x1498, + 0x0326, 0x0C98, 0x0329, 0x1298, 0x032A, 0x0A98, 0x032C, 0x0698, 0x0331, 0x1198, + 0x0332, 0x0998, 0x0334, 0x0598, 0x0338, 0x0398, 0x0343, 0x1858, 0x0345, 0x1458, + 0x0346, 0x0C58, 0x0349, 0x1258, 0x034A, 0x0A58, 0x034C, 0x0658, 0x0351, 0x1158, + 0x0352, 0x0958, 0x0354, 0x0558, 0x0361, 0x10D8, 0x0362, 0x08D8, 0x0364, 0x04D8, + 0x0383, 0x1838, 0x0385, 0x1438, 0x0386, 0x0C38, 0x0389, 0x1238, 0x038A, 0x0A38, + 0x038C, 0x0638, 0x0391, 0x1138, 0x0392, 0x0938, 0x0394, 0x0538, 0x03A1, 0x10B8, + 0x03A2, 0x08B8, 0x03A4, 0x04B8, 0x03C1, 0x1078, 0x03C2, 0x0878, 0x03C4, 0x0478, + 0x040F, 0x1E04, 0x0417, 0x1D04, 0x041B, 0x1B04, 0x041D, 0x1704, 0x041E, 0x0F04, + 0x0427, 0x1C84, 0x042B, 0x1A84, 0x042D, 0x1684, 0x042E, 0x0E84, 0x0433, 0x1984, + 0x0435, 0x1584, 0x0436, 0x0D84, 0x0439, 0x1384, 0x043A, 0x0B84, 0x043C, 0x0784, + 0x0447, 0x1C44, 0x044B, 0x1A44, 0x044D, 0x1644, 0x044E, 0x0E44, 0x0453, 0x1944, + 0x0455, 0x1544, 0x0456, 0x0D44, 0x0459, 0x1344, 0x045A, 0x0B44, 0x045C, 0x0744, + 0x0463, 0x18C4, 0x0465, 0x14C4, 0x0466, 0x0CC4, 0x0469, 0x12C4, 0x046A, 0x0AC4, + 0x046C, 0x06C4, 0x0471, 0x11C4, 0x0472, 0x09C4, 0x0474, 0x05C4, 0x0487, 0x1C24, + 0x048B, 0x1A24, 0x048D, 0x1624, 0x048E, 0x0E24, 0x0493, 0x1924, 0x0495, 0x1524, + 0x0496, 0x0D24, 0x0499, 0x1324, 0x049A, 0x0B24, 0x049C, 0x0724, 0x04A3, 0x18A4, + 0x04A5, 0x14A4, 0x04A6, 0x0CA4, 0x04A9, 0x12A4, 0x04AA, 0x0AA4, 0x04AC, 0x06A4, + 0x04B1, 0x11A4, 0x04B2, 0x09A4, 0x04B4, 0x05A4, 0x04C3, 0x1864, 0x04C5, 0x1464, + 0x04C6, 0x0C64, 0x04C9, 0x1264, 0x04CA, 0x0A64, 0x04CC, 0x0664, 0x04D1, 0x1164, + 0x04D2, 0x0964, 0x04D4, 0x0564, 0x04E1, 0x10E4, 0x04E2, 0x08E4, 0x0507, 0x1C14, + 0x050B, 0x1A14, 0x050D, 0x1614, 0x050E, 0x0E14, 0x0513, 0x1914, 0x0515, 0x1514, + 0x0516, 0x0D14, 0x0519, 0x1314, 0x051A, 0x0B14, 0x051C, 0x0714, 0x0523, 0x1894, + 0x0525, 0x1494, 0x0526, 0x0C94, 0x0529, 0x1294, 0x052A, 0x0A94, 0x052C, 0x0694, + 0x0531, 0x1194, 0x0532, 0x0994, 0x0534, 0x0594, 0x0543, 0x1854, 0x0545, 0x1454, + 0x0546, 0x0C54, 0x0549, 0x1254, 0x054A, 0x0A54, 0x054C, 0x0654, 0x0551, 0x1154, + 0x0552, 0x0954, 0x0561, 0x10D4, 0x0562, 0x08D4, 0x0583, 0x1834, 0x0585, 0x1434, + 0x0586, 0x0C34, 0x0589, 0x1234, 0x058A, 0x0A34, 0x058C, 0x0634, 0x0591, 0x1134, + 0x0592, 0x0934, 0x05A1, 0x10B4, 0x05A2, 0x08B4, 0x05C1, 0x1074, 0x05C2, 0x0874, + 0x0607, 0x1C0C, 0x060B, 0x1A0C, 0x060D, 0x160C, 0x060E, 0x0E0C, 0x0613, 0x190C, + 0x0615, 0x150C, 0x0616, 0x0D0C, 0x0619, 0x130C, 0x061A, 0x0B0C, 0x061C, 0x070C, + 0x0623, 0x188C, 0x0625, 0x148C, 0x0626, 0x0C8C, 0x0629, 0x128C, 0x062A, 0x0A8C, + 0x062C, 0x068C, 0x0631, 0x118C, 0x0632, 0x098C, 0x0643, 0x184C, 0x0645, 0x144C, + 0x0646, 0x0C4C, 0x0649, 0x124C, 0x064A, 0x0A4C, 0x0651, 0x114C, 0x0652, 0x094C, + 0x0661, 0x10CC, 0x0662, 0x08CC, 0x0683, 0x182C, 0x0685, 0x142C, 0x0686, 0x0C2C, + 0x0689, 0x122C, 0x068A, 0x0A2C, 0x0691, 0x112C, 0x0692, 0x092C, 0x06A1, 0x10AC, + 0x06A2, 0x08AC, 0x06C1, 0x106C, 0x06C2, 0x086C, 0x0703, 0x181C, 0x0705, 0x141C, + 0x0706, 0x0C1C, 0x0709, 0x121C, 0x070A, 0x0A1C, 0x0711, 0x111C, 0x0712, 0x091C, + 0x0721, 0x109C, 0x0722, 0x089C, 0x0741, 0x105C, 0x0742, 0x085C, 0x0781, 0x103C, + 0x0782, 0x083C, 0x080F, 0x1E02, 0x0817, 0x1D02, 0x081B, 0x1B02, 0x081D, 0x1702, + 0x081E, 0x0F02, 0x0827, 0x1C82, 0x082B, 0x1A82, 0x082D, 0x1682, 0x082E, 0x0E82, + 0x0833, 0x1982, 0x0835, 0x1582, 0x0836, 0x0D82, 0x0839, 0x1382, 0x083A, 0x0B82, + 0x0847, 0x1C42, 0x084B, 0x1A42, 0x084D, 0x1642, 0x084E, 0x0E42, 0x0853, 0x1942, + 0x0855, 0x1542, 0x0856, 0x0D42, 0x0859, 0x1342, 0x085A, 0x0B42, 0x0863, 0x18C2, + 0x0865, 0x14C2, 0x0866, 0x0CC2, 0x0869, 0x12C2, 0x086A, 0x0AC2, 0x0871, 0x11C2, + 0x0872, 0x09C2, 0x0887, 0x1C22, 0x088B, 0x1A22, 0x088D, 0x1622, 0x088E, 0x0E22, + 0x0893, 0x1922, 0x0895, 0x1522, 0x0896, 0x0D22, 0x0899, 0x1322, 0x089A, 0x0B22, + 0x08A3, 0x18A2, 0x08A5, 0x14A2, 0x08A6, 0x0CA2, 0x08A9, 0x12A2, 0x08AA, 0x0AA2, + 0x08B1, 0x11A2, 0x08B2, 0x09A2, 0x08C3, 0x1862, 0x08C5, 0x1462, 0x08C6, 0x0C62, + 0x08C9, 0x1262, 0x08CA, 0x0A62, 0x08D1, 0x1162, 0x08D2, 0x0962, 0x08E1, 0x10E2, + 0x0907, 0x1C12, 0x090B, 0x1A12, 0x090D, 0x1612, 0x090E, 0x0E12, 0x0913, 0x1912, + 0x0915, 0x1512, 0x0916, 0x0D12, 0x0919, 0x1312, 0x091A, 0x0B12, 0x0923, 0x1892, + 0x0925, 0x1492, 0x0926, 0x0C92, 0x0929, 0x1292, 0x092A, 0x0A92, 0x0931, 0x1192, + 0x0932, 0x0992, 0x0943, 0x1852, 0x0945, 0x1452, 0x0946, 0x0C52, 0x0949, 0x1252, + 0x094A, 0x0A52, 0x0951, 0x1152, 0x0961, 0x10D2, 0x0983, 0x1832, 0x0985, 0x1432, + 0x0986, 0x0C32, 0x0989, 0x1232, 0x098A, 0x0A32, 0x0991, 0x1132, 0x09A1, 0x10B2, + 0x09C1, 0x1072, 0x0A07, 0x1C0A, 0x0A0B, 0x1A0A, 0x0A0D, 0x160A, 0x0A0E, 0x0E0A, + 0x0A13, 0x190A, 0x0A15, 0x150A, 0x0A16, 0x0D0A, 0x0A19, 0x130A, 0x0A1A, 0x0B0A, + 0x0A23, 0x188A, 0x0A25, 0x148A, 0x0A26, 0x0C8A, 0x0A29, 0x128A, 0x0A2A, 0x0A8A, + 0x0A31, 0x118A, 0x0A43, 0x184A, 0x0A45, 0x144A, 0x0A46, 0x0C4A, 0x0A49, 0x124A, + 0x0A51, 0x114A, 0x0A61, 0x10CA, 0x0A83, 0x182A, 0x0A85, 0x142A, 0x0A86, 0x0C2A, + 0x0A89, 0x122A, 0x0A91, 0x112A, 0x0AA1, 0x10AA, 0x0AC1, 0x106A, 0x0B03, 0x181A, + 0x0B05, 0x141A, 0x0B06, 0x0C1A, 0x0B09, 0x121A, 0x0B11, 0x111A, 0x0B21, 0x109A, + 0x0B41, 0x105A, 0x0B81, 0x103A, 0x0C07, 0x1C06, 0x0C0B, 0x1A06, 0x0C0D, 0x1606, + 0x0C0E, 0x0E06, 0x0C13, 0x1906, 0x0C15, 0x1506, 0x0C16, 0x0D06, 0x0C19, 0x1306, + 0x0C23, 0x1886, 0x0C25, 0x1486, 0x0C26, 0x0C86, 0x0C29, 0x1286, 0x0C31, 0x1186, + 0x0C43, 0x1846, 0x0C45, 0x1446, 0x0C49, 0x1246, 0x0C51, 0x1146, 0x0C61, 0x10C6, + 0x0C83, 0x1826, 0x0C85, 0x1426, 0x0C89, 0x1226, 0x0C91, 0x1126, 0x0CA1, 0x10A6, + 0x0CC1, 0x1066, 0x0D03, 0x1816, 0x0D05, 0x1416, 0x0D09, 0x1216, 0x0D11, 0x1116, + 0x0D21, 0x1096, 0x0D41, 0x1056, 0x0D81, 0x1036, 0x0E03, 0x180E, 0x0E05, 0x140E, + 0x0E09, 0x120E, 0x0E11, 0x110E, 0x0E21, 0x108E, 0x0E41, 0x104E, 0x0E81, 0x102E, + 0x0F01, 0x101E, 0x100F, 0x1E01, 0x1017, 0x1D01, 0x101B, 0x1B01, 0x101D, 0x1701, + 0x1027, 0x1C81, 0x102B, 0x1A81, 0x102D, 0x1681, 0x1033, 0x1981, 0x1035, 0x1581, + 0x1039, 0x1381, 0x1047, 0x1C41, 0x104B, 0x1A41, 0x104D, 0x1641, 0x1053, 0x1941, + 0x1055, 0x1541, 0x1059, 0x1341, 0x1063, 0x18C1, 0x1065, 0x14C1, 0x1069, 0x12C1, + 0x1071, 0x11C1, 0x1087, 0x1C21, 0x108B, 0x1A21, 0x108D, 0x1621, 0x1093, 0x1921, + 0x1095, 0x1521, 0x1099, 0x1321, 0x10A3, 0x18A1, 0x10A5, 0x14A1, 0x10A9, 0x12A1, + 0x10B1, 0x11A1, 0x10C3, 0x1861, 0x10C5, 0x1461, 0x10C9, 0x1261, 0x10D1, 0x1161, + 0x1107, 0x1C11, 0x110B, 0x1A11, 0x110D, 0x1611, 0x1113, 0x1911, 0x1115, 0x1511, + 0x1119, 0x1311, 0x1123, 0x1891, 0x1125, 0x1491, 0x1129, 0x1291, 0x1131, 0x1191, + 0x1143, 0x1851, 0x1145, 0x1451, 0x1149, 0x1251, 0x1183, 0x1831, 0x1185, 0x1431, + 0x1189, 0x1231, 0x1207, 0x1C09, 0x120B, 0x1A09, 0x120D, 0x1609, 0x1213, 0x1909, + 0x1215, 0x1509, 0x1219, 0x1309, 0x1223, 0x1889, 0x1225, 0x1489, 0x1229, 0x1289, + 0x1243, 0x1849, 0x1245, 0x1449, 0x1283, 0x1829, 0x1285, 0x1429, 0x1303, 0x1819, + 0x1305, 0x1419, 0x1407, 0x1C05, 0x140B, 0x1A05, 0x140D, 0x1605, 0x1413, 0x1905, + 0x1415, 0x1505, 0x1423, 0x1885, 0x1425, 0x1485, 0x1443, 0x1845, 0x1483, 0x1825, + 0x1503, 0x1815, 0x1603, 0x180D, 0x1807, 0x1C03, 0x180B, 0x1A03, 0x1813, 0x1903, + 0x1823, 0x1883, 0x1843, 0x1445, 0x1249, 0x1151, 0x10E1, 0x0C46, 0x0A4A, 0x0952, + 0x08E2, 0x064C, 0x0554, 0x04E4, 0x0358, 0x02E8, 0x01F0 }; + +static unsigned short AppxD_II[78] = { /* Appendix D Table II - 2 of 13 characters */ + 0x0003, 0x1800, 0x0005, 0x1400, 0x0006, 0x0C00, 0x0009, 0x1200, 0x000A, 0x0A00, + 0x000C, 0x0600, 0x0011, 0x1100, 0x0012, 0x0900, 0x0014, 0x0500, 0x0018, 0x0300, + 0x0021, 0x1080, 0x0022, 0x0880, 0x0024, 0x0480, 0x0028, 0x0280, 0x0030, 0x0180, + 0x0041, 0x1040, 0x0042, 0x0840, 0x0044, 0x0440, 0x0048, 0x0240, 0x0050, 0x0140, + 0x0060, 0x00C0, 0x0081, 0x1020, 0x0082, 0x0820, 0x0084, 0x0420, 0x0088, 0x0220, + 0x0090, 0x0120, 0x0101, 0x1010, 0x0102, 0x0810, 0x0104, 0x0410, 0x0108, 0x0210, + 0x0201, 0x1008, 0x0202, 0x0808, 0x0204, 0x0408, 0x0401, 0x1004, 0x0402, 0x0804, + 0x0801, 0x1002, 0x1001, 0x0802, 0x0404, 0x0208, 0x0110, 0x00A0 }; + +static int AppxD_IV[130] = { /* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */ + 67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119, 115, 72, 97, + 2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112, 70, 100, 39, 30, 107, + 15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61, 99, 80, 90, 37, 123, 51, 25, 84, + 129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102, 21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53, + 60, 14, 1, 27, 103, 126, 75, 89, 50, 120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55, + 5, 74, 22, 101, 128, 58, 118, 48, 108, 38, 98, 93, 23, 83, 13, 73, 3 }; + +/*************************************************************************** + ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence + ** + ** Inputs: + ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which + ** are right justified - ie: the leftmost 2 bits of the first byte do not + ** hold data and must be set to zero. + ** + ** Outputs: + ** return unsigned short - 11 bit Frame Check Sequence (right justified) +***************************************************************************/ +extern unsigned short + USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr ) + +{ + unsigned short GeneratorPolynomial = 0x0F35; + unsigned short FrameCheckSequence = 0x07FF; + unsigned short Data; + int ByteIndex, Bit; + + /* Do most significant byte skipping the 2 most significant bits */ + Data = *ByteArrayPtr << 5; + ByteArrayPtr++; + for ( Bit = 2; Bit < 8; Bit++ ) + { + if ( (FrameCheckSequence ^ Data) & 0x400 ) + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + else + FrameCheckSequence = (FrameCheckSequence << 1); + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + /* Do rest of the bytes */ + for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ ) + { + Data = *ByteArrayPtr << 3; + ByteArrayPtr++; + for ( Bit = 0; Bit < 8; Bit++ ) + { + if ( (FrameCheckSequence ^ Data) & 0x0400 ) { + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } else { + FrameCheckSequence = (FrameCheckSequence << 1); + } + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + } + return FrameCheckSequence; +} + +void breakup(short int fcs_bit[], unsigned short usps_crc) +{ + int i; + + for(i = 0; i < 13; i++) { + fcs_bit[i] = 0; + } + + if(usps_crc >= 4096) { + fcs_bit[12] = 1; + usps_crc -= 4096; + } + if(usps_crc >= 2048) { + fcs_bit[11] = 1; + usps_crc -= 2048; + } + if(usps_crc >= 1024) { + fcs_bit[10] = 1; + usps_crc -= 1024; + } + if(usps_crc >= 512) { + fcs_bit[9] = 1; + usps_crc -= 512; + } + if(usps_crc >= 256) { + fcs_bit[8] = 1; + usps_crc -= 256; + } + if(usps_crc >= 128) { + fcs_bit[7] = 1; + usps_crc -= 128; + } + if(usps_crc >= 64) { + fcs_bit[6] = 1; + usps_crc -= 64; + } + if(usps_crc >= 32) { + fcs_bit[5] = 1; + usps_crc -= 32; + } + if(usps_crc >= 16) { + fcs_bit[4] = 1; + usps_crc -= 16; + } + if(usps_crc >= 8) { + fcs_bit[3] = 1; + usps_crc -= 8; + } + if(usps_crc >= 4) { + fcs_bit[2] = 1; + usps_crc -= 4; + } + if(usps_crc >= 2) { + fcs_bit[1] = 1; + usps_crc -= 2; + } + if(usps_crc == 1) { + fcs_bit[0] = 1; + } +} + +int imail(struct zint_symbol *symbol, unsigned char source[], int length) +{ + char data_pattern[200]; + int error_number; + int i, j, read; + char zip[35], tracker[35], zip_adder[11], temp[2]; + short int accum[112], x_reg[112], y_reg[112]; + unsigned char byte_array[13]; + unsigned short usps_crc; + int codeword[10]; + unsigned short characters[10]; + short int bit_pattern[13], bar_map[130]; + + error_number = 0; + + if(length > 32) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(SODIUM, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + strcpy(zip, ""); + strcpy(tracker, ""); + + /* separate the tracking code from the routing code */ + + read = 0; + j = 0; + for(i = 0; i < length; i++) { + if(source[i] == '-') { + tracker[read] = '\0'; + j = 1; + read = 0; + } else { + if(j == 0) { + /* reading tracker */ + tracker[read] = source[i]; + read++; + } else { + /* reading zip code */ + zip[read] = source[i]; + read++; + } + } + } + if(j == 0) { + tracker[read] = '\0'; + } else { + zip[read] = '\0'; + } + + if(strlen(tracker) != 20) { + strcpy(symbol->errtxt, "Invalid length tracking code"); + return ERROR_INVALID_DATA; + } + if(strlen(zip) > 11) { + strcpy(symbol->errtxt, "Invalid ZIP code"); + return ERROR_INVALID_DATA; + } + + /* *** Step 1 - Conversion of Data Fields into Binary Data *** */ + + /* Routing code first */ + + for(i = 0; i < 112; i++) { + accum[i] = 0; + } + + for(read = 0; read < strlen(zip); read++) { + + for(i = 0; i < 112; i++) { + x_reg[i] = accum[i]; + } + + for(i = 0; i < 9; i++) { + binary_add(accum, x_reg); + } + + x_reg[0] = BCD[ctoi(zip[read]) * 4]; + x_reg[1] = BCD[(ctoi(zip[read]) * 4) + 1]; + x_reg[2] = BCD[(ctoi(zip[read]) * 4) + 2]; + x_reg[3] = BCD[(ctoi(zip[read]) * 4) + 3]; + for(i = 4; i < 112; i++) { + x_reg[i] = 0; + } + + binary_add(accum, x_reg); + } + + /* add weight to routing code */ + + for(i = 0; i < 112; i++) { + x_reg[i] = accum[i]; + } + + if(strlen(zip) > 9) { + strcpy(zip_adder, "1000100001"); + } else { + if(strlen(zip) > 5) { + strcpy(zip_adder, "100001"); + } else { + if(strlen(zip) > 0) { + strcpy(zip_adder, "1"); + } else { + strcpy(zip_adder, "0"); + } + } + } + + for(i = 0; i < 112; i++) { + accum[i] = 0; + } + + for(read = 0; read < strlen(zip_adder); read++) { + + for(i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for(i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + y_reg[0] = BCD[ctoi(zip_adder[read]) * 4]; + y_reg[1] = BCD[(ctoi(zip_adder[read]) * 4) + 1]; + y_reg[2] = BCD[(ctoi(zip_adder[read]) * 4) + 2]; + y_reg[3] = BCD[(ctoi(zip_adder[read]) * 4) + 3]; + for(i = 4; i < 112; i++) { + y_reg[i] = 0; + } + + binary_add(accum, y_reg); + } + + binary_add(accum, x_reg); + + /* tracking code */ + + /* multiply by 10 */ + for(i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for(i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + /* add first digit of tracker */ + y_reg[0] = BCD[ctoi(tracker[0]) * 4]; + y_reg[1] = BCD[(ctoi(tracker[0]) * 4) + 1]; + y_reg[2] = BCD[(ctoi(tracker[0]) * 4) + 2]; + y_reg[3] = BCD[(ctoi(tracker[0]) * 4) + 3]; + for(i = 4; i < 112; i++) { + y_reg[i] = 0; + } + + binary_add(accum, y_reg); + + /* multiply by 5 */ + for(i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for(i = 0; i < 4; i++) { + binary_add(accum, y_reg); + } + + /* add second digit */ + y_reg[0] = BCD[ctoi(tracker[1]) * 4]; + y_reg[1] = BCD[(ctoi(tracker[1]) * 4) + 1]; + y_reg[2] = BCD[(ctoi(tracker[1]) * 4) + 2]; + y_reg[3] = BCD[(ctoi(tracker[1]) * 4) + 3]; + for(i = 4; i < 112; i++) { + y_reg[i] = 0; + } + + binary_add(accum, y_reg); + + /* and then the rest */ + + for(read = 2; read < strlen(tracker); read++) { + + for(i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for(i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + y_reg[0] = BCD[ctoi(tracker[read]) * 4]; + y_reg[1] = BCD[(ctoi(tracker[read]) * 4) + 1]; + y_reg[2] = BCD[(ctoi(tracker[read]) * 4) + 2]; + y_reg[3] = BCD[(ctoi(tracker[read]) * 4) + 3]; + for(i = 4; i < 112; i++) { + y_reg[i] = 0; + } + + binary_add(accum, y_reg); + } + + /* printf("Binary data 1: "); + hex_dump(accum); */ + + /* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */ + + accum[103] = 0; + accum[102] = 0; + + memset(byte_array, 0, 13); + for(j = 0; j < 13; j++) { + i = 96 - (8 * j); + byte_array[j] = 0; + byte_array[j] += accum[i]; + byte_array[j] += 2 * accum[i + 1]; + byte_array[j] += 4 * accum[i + 2]; + byte_array[j] += 8 * accum[i + 3]; + byte_array[j] += 16 * accum[i + 4]; + byte_array[j] += 32 * accum[i + 5]; + byte_array[j] += 64 * accum[i + 6]; + byte_array[j] += 128 * accum[i + 7]; + } + + usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array); + /* printf("FCS 2: %4.4X\n", usps_crc); */ + + /* *** Step 3 - Conversion from Binary Data to Codewords *** */ + + /* start with codeword J which is base 636 */ + for(i = 0; i < 112; i++) { + x_reg[i] = 0; + y_reg[i] = 0; + } + + x_reg[101] = 1; + x_reg[98] = 1; + x_reg[97] = 1; + x_reg[96] = 1; + x_reg[95] = 1; + x_reg[94] = 1; + + for(i = 92; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + codeword[9] = (accum[9] * 512) + (accum[8] * 256) + (accum[7] * 128) + (accum[6] * 64) + + (accum[5] * 32) + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + + (accum[1] * 2) + accum[0]; + + /* then codewords I to B with base 1365 */ + + for(j = 8; j > 0; j--) { + for(i = 0; i < 112; i++) { + accum[i] = y_reg[i]; + y_reg[i] = 0; + x_reg[i] = 0; + } + x_reg[101] = 1; + x_reg[99] = 1; + x_reg[97] = 1; + x_reg[95] = 1; + x_reg[93] = 1; + x_reg[91] = 1; + for(i = 91; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + codeword[j] = (accum[10] * 1024) + (accum[9] * 512) + (accum[8] * 256) + + (accum[7] * 128) + (accum[6] * 64) + (accum[5] * 32) + + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + + (accum[1] * 2) + accum[0]; + } + + codeword[0] = (y_reg[10] * 1024) + (y_reg[9] * 512) + (y_reg[8] * 256) + + (y_reg[7] * 128) + (y_reg[6] * 64) + (y_reg[5] * 32) + + (y_reg[4] * 16) + (y_reg[3] * 8) + (y_reg[2] * 4) + + (y_reg[1] * 2) + y_reg[0]; + + for(i = 0; i < 8; i++) { + if(codeword[i] == 1365) { + codeword[i] = 0; + codeword[i + 1]++; + } + } + + /* printf("Codewords 3: "); + for(i = 0; i < 10; i++) { + printf("%d ", codeword[i]); + } + printf("\n"); */ + + /* *** Step 4 - Inserting Additional Information into Codewords *** */ + + codeword[9] = codeword[9] * 2; + + if(usps_crc >= 1024) { + codeword[0] += 659; + } + + /* printf("Codewords 4b: "); + for(i = 0; i < 10; i++) { + printf("%d ", codeword[i]); + } + printf("\n"); */ + + /* *** Step 5 - Conversion from Codewords to Characters *** */ + + for(i = 0; i < 10; i++) { + if(codeword[i] < 1287) { + characters[i] = AppxD_I[codeword[i]]; + } else { + characters[i] = AppxD_II[codeword[i] - 1287]; + } + } + + /* printf("Characters 5a: "); + for(i = 0; i < 10; i++) { + printf("%4.4X ", characters[i]); + } + printf("\n"); */ + + breakup(bit_pattern, usps_crc); + + for(i = 0; i < 10; i++) { + if(bit_pattern[i] == 1) { + characters[i] = 0x1FFF - characters[i]; + } + } + + /* printf("Characters 5b: "); + for(i = 0; i < 10; i++) { + printf("%4.4X ", characters[i]); + } + printf("\n"); */ + + /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */ + + for(i = 0; i < 10; i++) { + breakup(bit_pattern, characters[i]); + for(j = 0; j < 13; j++) { + bar_map[AppxD_IV[(13 * i) + j] - 1] = bit_pattern[j]; + } + } + + strcpy(data_pattern, ""); + temp[1] = '\0'; + for(i = 0; i < 65; i++) { + j = 0; + if(bar_map[i] == 0) + j += 1; + if(bar_map[i + 65] == 0) + j += 2; + temp[0] = itoc(j); + concat(data_pattern, temp); + } + + /* Translate 4-state data pattern to symbol */ + read = 0; + for(i = 0; i < strlen(data_pattern); i++) + { + if((data_pattern[i] == '1') || (data_pattern[i] == '0')) + { + set_module(symbol, 0, read); + } + set_module(symbol, 1, read); + if((data_pattern[i] == '2') || (data_pattern[i] == '0')) + { + set_module(symbol, 2, read); + } + read += 2; + } + + symbol->row_height[0] = 2; + symbol->row_height[1] = 2; + symbol->row_height[2] = 2; + + symbol->rows = 3; + symbol->width = read - 1; + return error_number; +} diff --git a/backend/large.c b/backend/large.c new file mode 100644 index 00000000..fbd7aeb7 --- /dev/null +++ b/backend/large.c @@ -0,0 +1,227 @@ +/* large.c - Handles binary manipulation of large numbers */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include "common.h" +#include "large.h" + +static short int BCD[40] = { + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 0, 0, + 1, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 0, + 0, 0, 0, 1, + 1, 0, 0, 1 }; + +void binary_add(short int accumulator[], short int input_buffer[]) +{ /* Binary addition */ + int i, carry, done; + carry = 0; + + for(i = 0; i < 112; i++) { + done = 0; + if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) { + accumulator[i] = 0; + carry = 0; + done = 1; + } + if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) { + accumulator[i] = 1; + carry = 1; + done = 1; + } + } +} + +void binary_subtract(short int accumulator[], short int input_buffer[]) +{ /* 2's compliment subtraction */ + /* take input_buffer from accumulator and put answer in accumulator */ + int i; + short int sub_buffer[112]; + + for(i = 0; i < 112; i++) { + if(input_buffer[i] == 0) { + sub_buffer[i] = 1; + } else { + sub_buffer[i] = 0; + } + } + binary_add(accumulator, sub_buffer); + + sub_buffer[0] = 1; + + for(i = 1; i < 112; i++) { + sub_buffer[i] = 0; + } + binary_add(accumulator, sub_buffer); +} + +void shiftdown(short int buffer[]) +{ + int i; + + buffer[102] = 0; + buffer[103] = 0; + + for(i = 0; i < 102; i++) { + buffer[i] = buffer[i + 1]; + } +} + +void shiftup(short int buffer[]) +{ + int i; + + for(i = 102; i > 0; i--) { + buffer[i] = buffer[i - 1]; + } + + buffer[0] = 0; +} + +short int islarger(short int accum[], short int reg[]) +{ + /* Returns 1 if accum[] is larger than reg[], else 0 */ + int i, latch, larger; + latch = 0; + i = 103; + larger = 0; + + + do { + if((accum[i] == 1) && (reg[i] == 0)) { + latch = 1; + larger = 1; + } + if((accum[i] == 0) && (reg[i] == 1)) { + latch = 1; + } + i--; + } while ((latch == 0) && (i >= -1)); + + return larger; +} + +void binary_load(short int reg[], char data[], const unsigned int src_len) +{ + int read, i; + short int temp[112] = { 0 }; + + for(i = 0; i < 112; i++) { + reg[i] = 0; + } + + for(read = 0; read < src_len; read++) { + + for(i = 0; i < 112; i++) { + temp[i] = reg[i]; + } + + for(i = 0; i < 9; i++) { + binary_add(reg, temp); + } + + temp[0] = BCD[ctoi(data[read]) * 4]; + temp[1] = BCD[(ctoi(data[read]) * 4) + 1]; + temp[2] = BCD[(ctoi(data[read]) * 4) + 2]; + temp[3] = BCD[(ctoi(data[read]) * 4) + 3]; + for(i = 4; i < 112; i++) { + temp[i] = 0; + } + + binary_add(reg, temp); + } +} + +void hex_dump(short int input_buffer[]) +{ + int i, digit, byte_space; + + byte_space = 1; + for(i = 100; i >= 0; i-=4) { + digit = 0; + digit += 1 * input_buffer[i]; + digit += 2 * input_buffer[i + 1]; + digit += 4 * input_buffer[i + 2]; + digit += 8 * input_buffer[i + 3]; + + switch(digit) { + case 0: printf("0"); break; + case 1: printf("1"); break; + case 2: printf("2"); break; + case 3: printf("3"); break; + case 4: printf("4"); break; + case 5: printf("5"); break; + case 6: printf("6"); break; + case 7: printf("7"); break; + case 8: printf("8"); break; + case 9: printf("9"); break; + case 10: printf("A"); break; + case 11: printf("B"); break; + case 12: printf("C"); break; + case 13: printf("D"); break; + case 14: printf("E"); break; + case 15: printf("F"); break; + } + if(byte_space == 1) { + byte_space = 0; + } else { + byte_space = 1; + printf(" "); + } + } + printf("\n"); +} diff --git a/backend/large.h b/backend/large.h new file mode 100644 index 00000000..72076b06 --- /dev/null +++ b/backend/large.h @@ -0,0 +1,40 @@ +/* large.h - Handles binary manipulation of large numbers */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ +#ifndef __LARGE_H +#define __LARGE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void binary_load(short int reg[], char data[], const unsigned int src_len); +extern void binary_add(short int accumulator[], short int input_buffer[]); +extern void binary_subtract(short int accumulator[], short int input_buffer[]); +extern void shiftdown(short int buffer[]); +extern void shiftup(short int buffer[]); +extern short int islarger(short int accum[], short int reg[]); +extern void hex_dump(short int input_buffer[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __LARGE_H */ diff --git a/backend/library.c b/backend/library.c new file mode 100644 index 00000000..c2dc570d --- /dev/null +++ b/backend/library.c @@ -0,0 +1,837 @@ +/* library.c - external functions of libzint + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" + +struct zint_symbol *ZBarcode_Create() +{ + struct zint_symbol *symbol; + int i, j; + + symbol = (struct zint_symbol*)malloc(sizeof(*symbol)); + if (!symbol) return NULL; + + memset(symbol, 0, sizeof(*symbol)); + symbol->symbology = BARCODE_CODE128; + symbol->height = 0; + symbol->whitespace_width = 0; + symbol->border_width = 0; + symbol->output_options = 0; + symbol->rows = 0; + symbol->width = 0; + strcpy(symbol->fgcolour, "000000"); + strcpy(symbol->bgcolour, "ffffff"); + strcpy(symbol->outfile, "out.png"); + symbol->scale = 1.0; + symbol->option_1 = -1; + symbol->option_2 = 0; + symbol->option_3 = 928; // PDF_MAX + symbol->show_hrt = 1; // Show human readable text + symbol->input_mode = DATA_MODE; + strcpy(symbol->primary, ""); + for(i = 0; i < 178; i++) { + for(j = 0; j < 1000; j++) { + unset_module(symbol, i, j); + } + symbol->row_height[i] = 0; + } + symbol->bitmap = NULL; + symbol->bitmap_width = 0; + symbol->bitmap_height = 0; + return symbol; +} + +void ZBarcode_Clear(struct zint_symbol *symbol) +{ + int i, j; + + for(i = 0; i < symbol->rows; i++) { + for(j = 0; j < symbol->width; j++) { + unset_module(symbol, i, j); + } + } + symbol->rows = 0; + symbol->width = 0; + symbol->text[0] = '\0'; + symbol->errtxt[0] = '\0'; + if (symbol->bitmap != NULL) + free(symbol->bitmap); + symbol->bitmap = NULL; + symbol->bitmap_width = 0; + symbol->bitmap_height = 0; +} + +void ZBarcode_Delete(struct zint_symbol *symbol) +{ + if (symbol->bitmap != NULL) + free(symbol->bitmap); + free(symbol); +} + +extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ +extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ +extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ +extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */ +extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */ +extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */ +extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ +extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ +extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */ +extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ +extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ +extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ +extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ +extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ +extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ +extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ +extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ +extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ +extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */ +extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */ +extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */ +extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ +extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ +extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ +extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ +extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ +extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ +extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */ +extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ +extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ +extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ +extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ +extern int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */ +extern int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ +extern int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */ +extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ +extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ +extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ +extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ +extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ +extern int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ +extern int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */ +extern int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ +extern int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ +extern int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ +extern int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ +extern int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */ +extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ +extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ +extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ +extern int code_49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ +extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ +extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ +extern int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ + +#ifndef NO_PNG +extern int png_handle(struct zint_symbol *symbol, int rotate_angle); +#endif + +extern int bmp_handle(struct zint_symbol *symbol, int rotate_angle); +extern int ps_plot(struct zint_symbol *symbol); +extern int svg_plot(struct zint_symbol *symbol); + +void error_tag(char error_string[], int error_number) +{ + char error_buffer[100]; + + if(error_number != 0) { + strcpy(error_buffer, error_string); + + if(error_number > 4) { + strcpy(error_string, "error: "); + } else { + strcpy(error_string, "warning: "); + } + + concat(error_string, error_buffer); + } +} + +int hibc(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int counter, error_number, i; + char to_process[40], temp[2], check_digit; + + if(length > 36) { + strcpy(symbol->errtxt, "Data too long for HIBC LIC"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(TECHNETIUM , source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + strcpy(to_process, "+"); + counter = 41; + for(i = 0; i < length; i++) { + counter += posn(TECHNETIUM, source[i]); + } + counter = counter % 43; + + if(counter < 10) { + check_digit = itoc(counter); + } else { + if(counter < 36) { + check_digit = (counter - 10) + 'A'; + } else { + switch(counter) { + case 36: check_digit = '-'; break; + case 37: check_digit = '.'; break; + case 38: check_digit = ' '; break; + case 39: check_digit = '$'; break; + case 40: check_digit = '/'; break; + case 41: check_digit = '+'; break; + case 42: check_digit = '%'; break; + default: check_digit = ' '; break; /* Keep compiler happy */ + } + } + } + + temp[0] = check_digit; + temp[1] = '\0'; + + concat(to_process, (char *)source); + concat(to_process, temp); + length = strlen(to_process); + + switch(symbol->symbology) { + case BARCODE_HIBC_128: + error_number = code_128(symbol, (unsigned char *)to_process, length); + ustrcpy(symbol->text, (unsigned char*)"*"); + uconcat(symbol->text, (unsigned char*)to_process); + uconcat(symbol->text, (unsigned char*)"*"); + break; + case BARCODE_HIBC_39: + symbol->option_2 = 0; + error_number = c39(symbol, (unsigned char *)to_process, length); + ustrcpy(symbol->text, (unsigned char*)"*"); + uconcat(symbol->text, (unsigned char*)to_process); + uconcat(symbol->text, (unsigned char*)"*"); + break; + case BARCODE_HIBC_DM: + error_number = dmatrix(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_QR: + error_number = qr_code(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_PDF: + error_number = pdf417enc(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_MICPDF: + error_number = micro_pdf417(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_AZTEC: + error_number = aztec(symbol, (unsigned char *)to_process, length); + break; + } + + return error_number; +} + +int gs1_compliant(int symbology) +{ + /* Returns 1 if symbology supports GS1 data */ + + int result = 0; + + switch(symbology) { + case BARCODE_EAN128: + case BARCODE_RSS_EXP: + case BARCODE_RSS_EXPSTACK: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CODE16K: + case BARCODE_AZTEC: + case BARCODE_DATAMATRIX: + case BARCODE_CODEONE: + case BARCODE_CODE49: + case BARCODE_QRCODE: + result = 1; + break; + } + + return result; +} + +int ZBarcode_ValidID(int symbol_id) +{ + /* Checks whether a symbology is supported */ + + int result = 0; + + switch(symbol_id) { + case BARCODE_CODE11: + case BARCODE_C25MATRIX: + case BARCODE_C25INTER: + case BARCODE_C25IATA: + case BARCODE_C25LOGIC: + case BARCODE_C25IND: + case BARCODE_CODE39: + case BARCODE_EXCODE39: + case BARCODE_EANX: + case BARCODE_EAN128: + case BARCODE_CODABAR: + case BARCODE_CODE128: + case BARCODE_DPLEIT: + case BARCODE_DPIDENT: + case BARCODE_CODE16K: + case BARCODE_CODE49: + case BARCODE_CODE93: + case BARCODE_FLAT: + case BARCODE_RSS14: + case BARCODE_RSS_LTD: + case BARCODE_RSS_EXP: + case BARCODE_TELEPEN: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_POSTNET: + case BARCODE_MSI_PLESSEY: + case BARCODE_FIM: + case BARCODE_LOGMARS: + case BARCODE_PHARMA: + case BARCODE_PZN: + case BARCODE_PHARMA_TWO: + case BARCODE_PDF417: + case BARCODE_PDF417TRUNC: + case BARCODE_MAXICODE: + case BARCODE_QRCODE: + case BARCODE_CODE128B: + case BARCODE_AUSPOST: + case BARCODE_AUSREPLY: + case BARCODE_AUSROUTE: + case BARCODE_AUSREDIRECT: + case BARCODE_ISBNX: + case BARCODE_RM4SCC: + case BARCODE_DATAMATRIX: + case BARCODE_EAN14: + case BARCODE_NVE18: + case BARCODE_JAPANPOST: + case BARCODE_KOREAPOST: + case BARCODE_RSS14STACK: + case BARCODE_RSS14STACK_OMNI: + case BARCODE_RSS_EXPSTACK: + case BARCODE_PLANET: + case BARCODE_MICROPDF417: + case BARCODE_ONECODE: + case BARCODE_PLESSEY: + case BARCODE_TELEPEN_NUM: + case BARCODE_ITF14: + case BARCODE_KIX: + case BARCODE_AZTEC: + case BARCODE_DAFT: + case BARCODE_MICROQR: + case BARCODE_HIBC_128: + case BARCODE_HIBC_39: + case BARCODE_HIBC_DM: + case BARCODE_HIBC_QR: + case BARCODE_HIBC_PDF: + case BARCODE_HIBC_MICPDF: + case BARCODE_HIBC_AZTEC: + case BARCODE_AZRUNE: + case BARCODE_CODE32: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CHANNEL: + case BARCODE_CODEONE: + case BARCODE_GRIDMATRIX: + result = 1; + break; + } + + return result; +} + +int extended_charset(struct zint_symbol *symbol, unsigned char *source, int length) +{ + int error_number = 0; + + /* These are the "elite" standards which can support multiple character sets */ + switch(symbol->symbology) { + case BARCODE_QRCODE: error_number = qr_code(symbol, source, length); break; + case BARCODE_MICROQR: error_number = microqr(symbol, source, length); break; + case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length); break; + } + + return error_number; +} + +int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) +{ + /* These are the "norm" standards which only support Latin-1 at most */ + int error_number = 0; + +#ifndef _MSC_VER + unsigned char preprocessed[length + 1]; +#else + unsigned char* preprocessed = (unsigned char*)_alloca(length + 1); +#endif + + if(symbol->symbology == BARCODE_CODE16K) { + symbol->whitespace_width = 16; + symbol->border_width = 2; + symbol->output_options = BARCODE_BIND; + } + + if(symbol->symbology == BARCODE_ITF14) { + symbol->whitespace_width = 20; + symbol->border_width = 8; + symbol->output_options = BARCODE_BOX; + } + + switch(symbol->input_mode) { + case DATA_MODE: + case GS1_MODE: + memcpy(preprocessed, source, length); + preprocessed[length] = '\0'; + break; + case UNICODE_MODE: + error_number = latin1_process(symbol, source, preprocessed, &length); + if(error_number != 0) { return error_number; } + break; + } + + switch(symbol->symbology) { + case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length); break; + case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length); break; + case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length); break; + case BARCODE_UPCA: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_UPCE: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_EANX: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, length); break; + case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length); break; + case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length); break; + case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length); break; + case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length); break; + case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length); break; + case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length); break; + case BARCODE_CODE128: error_number = code_128(symbol, preprocessed, length); break; + case BARCODE_CODE128B: error_number = code_128(symbol, preprocessed, length); break; + case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length); break; + case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length); break; + case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length); break; + case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length); break; + case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length); break; + case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length); break; + case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length); break; + case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length); break; + case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length); break; + case BARCODE_FIM: error_number = fim(symbol, preprocessed, length); break; + case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length); break; + case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length); break; + case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length); break; + case BARCODE_AUSPOST: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSREPLY: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSROUTE: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSREDIRECT: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length); break; + case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length); break; + case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, length); break; + case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_RSS14: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK_OMNI: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, length); break; + case BARCODE_RSS_EXP: error_number = rssexpanded(symbol, preprocessed, length); break; + case BARCODE_RSS_EXPSTACK: error_number = rssexpanded(symbol, preprocessed, length); break; + case BARCODE_EANX_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_EAN128_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_LTD_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_EXP_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_UPCA_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_UPCE_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14_OMNI_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_EXPSTACK_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length); break; + case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length); break; + case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length); break; + case BARCODE_EAN14: error_number = ean_14(symbol, preprocessed, length); break; + case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length); break; + case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length); break; + case BARCODE_HIBC_128: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_39: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_DM: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_QR: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_PDF: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_MICPDF: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_AZTEC: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length); break; + case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length); break; + case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length); break; + case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length); break; + case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, length); break; + case BARCODE_PDF417: error_number = pdf417enc(symbol, preprocessed, length); break; + case BARCODE_PDF417TRUNC: error_number = pdf417enc(symbol, preprocessed, length); break; + case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, length); break; + case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, length); break; + case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, length); break; + } + + return error_number; +} + +int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) +{ + int error_number, error_buffer, i; + error_number = 0; + + if(length == 0) { + length = ustrlen(source); + } + if(length == 0) { + strcpy(symbol->errtxt, "No input data"); + error_tag(symbol->errtxt, ERROR_INVALID_DATA); + return ERROR_INVALID_DATA; + } + + +#ifndef _MSC_VER + unsigned char local_source[length + 1]; +#else + unsigned char* local_source = (unsigned char*)_alloca(length + 1); +#endif + + /* First check the symbology field */ + if(symbol->symbology < 1) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + + /* symbol->symbologys 1 to 86 are defined by tbarcode */ + if(symbol->symbology == 5) { symbol->symbology = BARCODE_C25MATRIX; } + if((symbol->symbology >= 10) && (symbol->symbology <= 12)) { symbol->symbology = BARCODE_EANX; } + if((symbol->symbology == 14) || (symbol->symbology == 15)) { symbol->symbology = BARCODE_EANX; } + if(symbol->symbology == 17) { symbol->symbology = BARCODE_UPCA; } + if(symbol->symbology == 19) { strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar"); symbol->symbology = BARCODE_CODABAR; error_number = WARN_INVALID_OPTION; } + if(symbol->symbology == 26) { symbol->symbology = BARCODE_UPCA; } + if(symbol->symbology == 27) { strcpy(symbol->errtxt, "UPCD1 not supported"); error_number = ERROR_INVALID_OPTION; } + if(symbol->symbology == 33) { symbol->symbology = BARCODE_EAN128; } + if((symbol->symbology == 35) || (symbol->symbology == 36)) { symbol->symbology = BARCODE_UPCA; } + if((symbol->symbology == 38) || (symbol->symbology == 39)) { symbol->symbology = BARCODE_UPCE; } + if((symbol->symbology >= 41) && (symbol->symbology <= 45)) { symbol->symbology = BARCODE_POSTNET; } + if(symbol->symbology == 46) { symbol->symbology = BARCODE_PLESSEY; } + if(symbol->symbology == 48) { symbol->symbology = BARCODE_NVE18; } + if(symbol->symbology == 54) { strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if((symbol->symbology == 59) || (symbol->symbology == 61)) { symbol->symbology = BARCODE_CODE128; } + if(symbol->symbology == 62) { symbol->symbology = BARCODE_CODE93; } + if((symbol->symbology == 64) || (symbol->symbology == 65)) { symbol->symbology = BARCODE_AUSPOST; } + if(symbol->symbology == 73) { strcpy(symbol->errtxt, "Codablock E not supported"); error_number = ERROR_INVALID_OPTION; } + if(symbol->symbology == 78) { symbol->symbology = BARCODE_RSS14; } + if(symbol->symbology == 83) { symbol->symbology = BARCODE_PLANET; } + if(symbol->symbology == 88) { symbol->symbology = BARCODE_EAN128; } + if(symbol->symbology == 91) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if((symbol->symbology >= 94) && (symbol->symbology <= 96)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if(symbol->symbology == 100) { symbol->symbology = BARCODE_HIBC_128; } + if(symbol->symbology == 101) { symbol->symbology = BARCODE_HIBC_39; } + if(symbol->symbology == 103) { symbol->symbology = BARCODE_HIBC_DM; } + if(symbol->symbology == 105) { symbol->symbology = BARCODE_HIBC_QR; } + if(symbol->symbology == 107) { symbol->symbology = BARCODE_HIBC_PDF; } + if(symbol->symbology == 109) { symbol->symbology = BARCODE_HIBC_MICPDF; } + if(symbol->symbology == 111) { symbol->symbology = BARCODE_HIBC_BLOCKF; } + if((symbol->symbology >= 113) && (symbol->symbology <= 127)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + /* Everything from 128 up is Zint-specific */ + if(symbol->symbology >= 143) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if((symbol->symbology == BARCODE_CODABLOCKF) || (symbol->symbology == BARCODE_HIBC_BLOCKF)) { strcpy(symbol->errtxt, "Codablock F not supported"); error_number = ERROR_INVALID_OPTION; } + + if(error_number > 4) { + error_tag(symbol->errtxt, error_number); + return error_number; + } else { + error_buffer = error_number; + } + + if((symbol->input_mode < 0) || (symbol->input_mode > 2)) { symbol->input_mode = DATA_MODE; } + + if(symbol->input_mode == GS1_MODE) { + for(i = 0; i < length; i++) { + if(source[i] == '\0') { + strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode"); + return ERROR_INVALID_DATA; + } + } + if(gs1_compliant(symbol->symbology) == 1) { + error_number = ugs1_verify(symbol, source, length, local_source); + if(error_number != 0) { return error_number; } + length = ustrlen(local_source); + } else { + strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode"); + return ERROR_INVALID_OPTION; + } + } else { + memcpy(local_source, source, length); + local_source[length] = '\0'; + } + + switch(symbol->symbology) { + case BARCODE_QRCODE: + case BARCODE_MICROQR: + case BARCODE_GRIDMATRIX: + error_number = extended_charset(symbol, local_source, length); + break; + default: + error_number = reduced_charset(symbol, local_source, length); + break; + } + + if((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) { + for(i = 0; i < length; i++) { + if(local_source[i] == '\0') { + symbol->text[i] = ' '; + } else { + symbol->text[i] = local_source[i]; + } + } + } + + if(error_number == 0) { + error_number = error_buffer; + } + error_tag(symbol->errtxt, error_number); + /*printf("%s\n",symbol->text);*/ + return error_number; +} + +int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) +{ + int error_number; + char output[4]; + + switch(rotate_angle) { + case 0: + case 90: + case 180: + case 270: + break; + default: + strcpy(symbol->errtxt, "Invalid rotation angle"); + return ERROR_INVALID_OPTION; + break; + } + + if(strlen(symbol->outfile) > 3) { + output[0] = symbol->outfile[strlen(symbol->outfile) - 3]; + output[1] = symbol->outfile[strlen(symbol->outfile) - 2]; + output[2] = symbol->outfile[strlen(symbol->outfile) - 1]; + output[3] = '\0'; + to_upper((unsigned char*)output); + +#ifndef NO_PNG + if(!(strcmp(output, "PNG"))) { + if(symbol->scale < 1.0) { symbol->text[0] = '\0'; } + error_number = png_handle(symbol, rotate_angle); + } else { +#endif + if(!(strcmp(output, "EPS"))) { + error_number = ps_plot(symbol); + } else { + if(!(strcmp(output, "SVG"))) { + error_number = svg_plot(symbol); + } else { + strcpy(symbol->errtxt, "Unknown output format"); + error_tag(symbol->errtxt, ERROR_INVALID_OPTION); + return ERROR_INVALID_OPTION; + } + } +#ifndef NO_PNG + } +#endif + } else { + strcpy(symbol->errtxt, "Unknown output format"); + error_tag(symbol->errtxt, ERROR_INVALID_OPTION); + return ERROR_INVALID_OPTION; + } + + error_tag(symbol->errtxt, error_number); + return error_number; +} + +int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) +{ + int error_number; + + switch(rotate_angle) { + case 0: + case 90: + case 180: + case 270: + break; + default: + strcpy(symbol->errtxt, "Invalid rotation angle"); + return ERROR_INVALID_OPTION; + break; + } + + error_number = bmp_handle(symbol, rotate_angle); + error_tag(symbol->errtxt, error_number); + return error_number; +} + +int ZBarcode_Print_Rotated(struct zint_symbol *symbol, int rotate_angle) { + /* Depreciated - will be removed in later version */ + return ZBarcode_Print(symbol, rotate_angle); +} + +int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode(symbol, input, length); + if(error_number != 0) { + return error_number; + } + + error_number = ZBarcode_Print(symbol, rotate_angle); + return error_number; +} + +int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode(symbol, input, length); + if(error_number != 0) { + return error_number; + } + + error_number = ZBarcode_Buffer(symbol, rotate_angle); + return error_number; +} + +int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char *input, int rotate_angle) { + /* Depreciated - will be removed in later version */ + return ZBarcode_Encode_and_Print(symbol, input, rotate_angle, strlen((char *)input)); +} + +int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) +{ + FILE *file; + unsigned char *buffer; + unsigned long fileLen; + unsigned int nRead = 0, n = 0; + int ret; + + file = fopen(filename, "rb"); + if (!file) { + strcpy(symbol->errtxt, "Unable to read input file"); + return ERROR_INVALID_DATA; + } + + /* Get file length */ + fseek(file, 0, SEEK_END); + fileLen = ftell(file); + fseek(file, 0, SEEK_SET); + + if(fileLen > 7100) { + /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ + strcpy(symbol->errtxt, "Input file too long"); + fclose(file); + return ERROR_INVALID_DATA; + } + + /* Allocate memory */ + buffer = (unsigned char *)malloc(fileLen * sizeof(unsigned char)); + if(!buffer) { + strcpy(symbol->errtxt, "Internal memory error"); + fclose(file); + return ERROR_MEMORY; + } + + /* Read file contents into buffer */ + + do + { + n = fread(buffer + nRead, 1, fileLen - nRead, file); + if (ferror(file)) + { + strcpy(symbol->errtxt, strerror(errno)); + nRead = 0; + return ERROR_INVALID_DATA; + } + nRead += n; + } while (!feof(file) && (0 < n) && (nRead < fileLen)); + + fclose(file); + ret = ZBarcode_Encode(symbol, buffer, nRead); + free(buffer); + return ret; +} + +int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode_File(symbol, filename); + if(error_number != 0) { + return error_number; + } + + return ZBarcode_Print(symbol, rotate_angle); +} + +int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode_File(symbol, filename); + if(error_number != 0) { + return error_number; + } + + return ZBarcode_Buffer(symbol, rotate_angle); +} diff --git a/backend/libzint.rc b/backend/libzint.rc new file mode 100644 index 00000000..40008a4c --- /dev/null +++ b/backend/libzint.rc @@ -0,0 +1,42 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO +#endif + FILEVERSION 2,3,0,0 + PRODUCTVERSION 2,3,0,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "libzint barcode library\0" + VALUE "FileVersion", "2.3.0.0\0" + VALUE "InternalName", "zint.dll\0" + VALUE "LegalCopyright", "Copyright 2009 Robin Stuart & BogDan Vatra\0" + VALUE "OriginalFilename", "zint.dll\0" + VALUE "ProductName", "libzint\0" + VALUE "ProductVersion", "2.3.0.0\0" + VALUE "License", "GNU General Public License version 3\0" + VALUE "WWW", "http://www.sourceforge.net/projects/zint\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1250 + END +END diff --git a/backend/maxicode.c b/backend/maxicode.c new file mode 100644 index 00000000..3e77d909 --- /dev/null +++ b/backend/maxicode.c @@ -0,0 +1,702 @@ +/* maxicode.c - Handles Maxicode */ + +/* + libzint - the open source barcode library + Copyright (C) 2010 Robin Stuart + + 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. +*/ + +/* Includes corrections thanks to Monica Swanson @ Source Technologies */ + +#include "common.h" +#include "maxicode.h" +#include "reedsol.h" +#include +#include +#include + +int maxi_codeword[144]; + +void maxi_do_primary_check( ) +{ + /* Handles error correction of primary message */ + unsigned char data[15]; + unsigned char results[15]; + int j; + int datalen = 10; + int ecclen = 10; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + for(j = 0; j < datalen; j += 1) + data[j] = maxi_codeword[j]; + + rs_encode(datalen, data, results); + + for ( j = 0; j < ecclen; j += 1) + maxi_codeword[ datalen + j] = results[ecclen - 1 - j]; + rs_free(); +} + +void maxi_do_secondary_chk_odd( int ecclen ) +{ + /* Handles error correction of odd characters in secondary */ + unsigned char data[100]; + unsigned char results[30]; + int j; + int datalen = 68; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + if (ecclen == 20) + datalen = 84; + + for(j = 0; j < datalen; j += 1) + if ((j % 2) == 1) // odd + data[(j-1)/2] = maxi_codeword[j + 20]; + + rs_encode(datalen/2, data, results); + + for ( j = 0; j < (ecclen); j += 1) + maxi_codeword[ datalen + (2 *j) + 1 + 20 ] = results[ecclen - 1 - j]; + rs_free(); +} + +void maxi_do_secondary_chk_even(int ecclen ) +{ + /* Handles error correction of even characters in secondary */ + unsigned char data[100]; + unsigned char results[30]; + int j; + int datalen = 68; + + if (ecclen == 20) + datalen = 84; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + for(j = 0; j < datalen + 1; j += 1) + if ((j % 2) == 0) // even + data[j/2] = maxi_codeword[j + 20]; + + rs_encode(datalen/2, data, results); + + for ( j = 0; j < (ecclen); j += 1) + maxi_codeword[ datalen + (2 *j) + 20] = results[ecclen - 1 - j]; + rs_free(); +} + +void maxi_bump(int set[], int character[], int bump_posn) +{ + /* Moves everything up so that a shift or latch can be inserted */ + int i; + + for(i = 143; i > bump_posn; i--) { + set[i] = set[i - 1]; + character[i] = character[i - 1]; + } +} + +int maxi_text_process(int mode, unsigned char source[], int length) +{ + /* Format text according to Appendix A */ + + /* This code doesn't make use of [Lock in C], [Lock in D] + and [Lock in E] and so is not always the most efficient at + compressing data, but should suffice for most applications */ + + int set[144], character[144], i, j, done, count, current_set; + + if(length > 138) { + return ERROR_TOO_LONG; + } + + for(i = 0; i < 144; i++) { + set[i] = -1; + character[i] = 0; + } + + for (i = 0; i < length; i++) { + /* Look up characters in table from Appendix A - this gives + value and code set for most characters */ + set[i] = maxiCodeSet[source[i]]; + character[i] = maxiSymbolChar[source[i]]; + } + + /* If a character can be represented in more than one code set, + pick which version to use */ + if(set[0] == 0) { + if(character[0] == 13) { + character[0] = 0; + } + set[0] = 1; + } + + for(i = 1; i < length; i++) { + if(set[i] == 0) { + done = 0; + /* Special character */ + if(character[i] == 13) { + /* Carriage Return */ + if(set[i - 1] == 5) { + character[i] = 13; + set[i] = 5; + } else { + if((i != length - 1) && (set[i + 1] == 5)) { + character[i] = 13; + set[i] = 5; + } else { + character[i] = 0; + set[i] = 1; + } + } + done = 1; + } + + if((character[i] == 28) && (done == 0)) { + /* FS */ + if(set[i - 1] == 5) { + character[i] = 32; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if((character[i] == 29) && (done == 0)) { + /* GS */ + if(set[i - 1] == 5) { + character[i] = 33; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if((character[i] == 30) && (done == 0)) { + /* RS */ + if(set[i - 1] == 5) { + character[i] = 34; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if((character[i] == 32) && (done == 0)) { + /* Space */ + if(set[i - 1] == 1) { + character[i] = 32; + set[i] = 1; + } + if(set[i - 1] == 2) { + character[i] = 47; + set[i] = 2; + } + if(set[i - 1] >= 3) { + if(i != length - 1) { + if(set[i + 1] == 1) { + character[i] = 32; + set[i] = 1; + } + if(set[i + 1] == 2) { + character[i] = 47; + set[i] = 2; + } + if(set[i + 1] >= 3) { + character[i] = 59; + set[i] = set[i - 1]; + } + } else { + character[i] = 59; + set[i] = set[i - 1]; + } + } + done = 1; + } + + if((character[i] == 44) && (done == 0)) { + /* Comma */ + if(set[i - 1] == 2) { + character[i] = 48; + set[i] = 2; + } else { + if((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 48; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if((character[i] == 46) && (done == 0)) { + /* Full Stop */ + if(set[i - 1] == 2) { + character[i] = 49; + set[i] = 2; + } else { + if((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 49; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if((character[i] == 47) && (done == 0)) { + /* Slash */ + if(set[i - 1] == 2) { + character[i] = 50; + set[i] = 2; + } else { + if((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 50; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if((character[i] == 58) && (done == 0)) { + /* Colon */ + if(set[i - 1] == 2) { + character[i] = 51; + set[i] = 2; + } else { + if((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 51; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + } + } + + for(i = length; i < 144; i++) { + /* Add the padding */ + if(set[length - 1] == 2) { + set[i] = 2; + } else { + set[i] = 1; + } + character[i] = 33; + } + + /* Find candidates for number compression */ + if((mode == 2) || (mode ==3)) { j = 0; } else { j = 9; } + /* Number compression not allowed in primary message */ + count = 0; + for(i = j; i < 143; i++) { + if((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) { + /* Character is a number */ + count++; + } else { + count = 0; + } + if(count == 9) { + /* Nine digits in a row can be compressed */ + set[i] = 6; + set[i - 1] = 6; + set[i - 2] = 6; + set[i - 3] = 6; + set[i - 4] = 6; + set[i - 5] = 6; + set[i - 6] = 6; + set[i - 7] = 6; + set[i - 8] = 6; + count = 0; + } + } + + /* Add shift and latch characters */ + current_set = 1; + i = 0; + do { + + if(set[i] != current_set) { + switch(set[i]) { + case 1: + if(set[i + 1] == 1) { + if(set[i + 2] == 1) { + if(set[i + 3] == 1) { + /* Latch A */ + maxi_bump(set, character, i); + character[i] = 63; + current_set = 1; + length++; + } else { + /* 3 Shift A */ + maxi_bump(set, character, i); + character[i] = 57; + length++; + i += 2; + } + } else { + /* 2 Shift A */ + maxi_bump(set, character, i); + character[i] = 56; + length++; + i++; + } + } else { + /* Shift A */ + maxi_bump(set, character, i); + character[i] = 59; + length++; + } + break; + case 2: + if(set[i + 1] == 2) { + /* Latch B */ + maxi_bump(set, character, i); + character[i] = 63; + current_set = 2; + length++; + } else { + /* Shift B */ + maxi_bump(set, character, i); + character[i] = 59; + length++; + } + break; + case 3: + /* Shift C */ + maxi_bump(set, character, i); + character[i] = 60; + length++; + break; + case 4: + /* Shift D */ + maxi_bump(set, character, i); + character[i] = 61; + length++; + break; + case 5: + /* Shift E */ + maxi_bump(set, character, i); + character[i] = 62; + length++; + break; + case 6: + /* Number Compressed */ + /* Do nothing */ + break; + } + i++; + } + i++; + } while(i < 145); + + /* Number compression has not been forgotten! - It's handled below */ + i = 0; + do { + if (set[i] == 6) { + /* Number compression */ + char substring[11]; + int value; + + for(j = 0; j < 10; j++) { + substring[j] = character[i + j]; + } + substring[10] = '\0'; + value = atoi(substring); + + character[i] = 31; /* NS */ + character[i + 1] = (value & 0x3f000000) >> 24; + character[i + 2] = (value & 0xfc0000) >> 18; + character[i + 3] = (value & 0x3f000) >> 12; + character[i + 4] = (value & 0xfc0) >> 6; + character[i + 5] = (value & 0x3f); + + i += 6; + for(j = i; j < 140; j++) { + set[j] = set[j + 3]; + character[j] = character[j + 3]; + } + length -= 3; + } else { + i++; + } + } while (i <= 143); + + if(((mode ==2) || (mode == 3)) && (length > 84)) { + return ERROR_TOO_LONG; + } + + if(((mode == 4) || (mode == 6)) && (length > 93)) { + return ERROR_TOO_LONG; + } + + if((mode == 5) && (length > 77)) { + return ERROR_TOO_LONG; + } + + + /* Copy the encoded text into the codeword array */ + if((mode == 2) || (mode == 3)) { + for(i = 0; i < 84; i++) { /* secondary only */ + maxi_codeword[i + 20] = character[i]; + } + } + + if((mode == 4) || (mode == 6)) { + for(i = 0; i < 9; i++) { /* primary */ + maxi_codeword[i + 1] = character[i]; + } + for(i = 0; i < 84; i++) { /* secondary */ + maxi_codeword[i + 20] = character[i + 9]; + } + } + + if(mode == 5) { + for(i = 0; i < 9; i++) { /* primary */ + maxi_codeword[i + 1] = character[i]; + } + for(i = 0; i < 68; i++) { /* secondary */ + maxi_codeword[i + 20] = character[i + 9]; + } + } + + return 0; +} + +void maxi_do_primary_2(char postcode[], int country, int service) +{ + /* Format structured primary for Mode 2 */ + int postcode_length, postcode_num, i; + + for(i = 0; i < 10; i++) { + if((postcode[i] < '0') || (postcode[i] > '9')) { + postcode[i] = '\0'; + } + } + + postcode_length = strlen(postcode); + postcode_num = atoi(postcode); + + maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2; + maxi_codeword[1] = ((postcode_num & 0xfc) >> 2); + maxi_codeword[2] = ((postcode_num & 0x3f00) >> 8); + maxi_codeword[3] = ((postcode_num & 0xfc000) >> 14); + maxi_codeword[4] = ((postcode_num & 0x3f00000) >> 20); + maxi_codeword[5] = ((postcode_num & 0x3c000000) >> 26) | ((postcode_length & 0x3) << 4); + maxi_codeword[6] = ((postcode_length & 0x3c) >> 2) | ((country & 0x3) << 4); + maxi_codeword[7] = (country & 0xfc) >> 2; + maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); + maxi_codeword[9] = ((service & 0x3f0) >> 4); +} + +void maxi_do_primary_3(char postcode[], int country, int service) +{ + /* Format structured primary for Mode 3 */ + int i, h; + + h = strlen(postcode); + to_upper((unsigned char*)postcode); + for(i = 0; i < h; i++) { + if((postcode[i] >= 'A') && (postcode[i] <= 'Z')) { + /* (Capital) letters shifted to Code Set A values */ + postcode[i] -= 64; + } + if(((postcode[i] == 27) || (postcode[i] == 31)) || ((postcode[i] == 33) || (postcode[i] >= 59))) { + /* Not a valid postcode character */ + postcode[i] = ' '; + } + /* Input characters lower than 27 (NUL - SUB) in postcode are + interpreted as capital letters in Code Set A (e.g. LF becomes 'J') */ + } + + maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3; + maxi_codeword[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3c) >> 2); + maxi_codeword[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3c) >> 2); + maxi_codeword[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3c) >> 2); + maxi_codeword[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3c) >> 2); + maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2); + maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4); + maxi_codeword[7] = (country & 0xfc) >> 2; + maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); + maxi_codeword[9] = ((service & 0x3f0) >> 4); +} + +int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0; + int bit_pattern[7], internal_error = 0, eclen, error_number; + char postcode[12], countrystr[4], servicestr[4]; + +#ifndef _MSC_VER + unsigned char local_source[length + 1]; +#else + unsigned char* local_source = (unsigned char*)_alloca(length + 1); +#endif + + mode = symbol->option_1; + strcpy(postcode, ""); + strcpy(countrystr, ""); + strcpy(servicestr, ""); + + /* The following to be replaced by ECI handling */ + switch(symbol->input_mode) { + case DATA_MODE: + case GS1_MODE: + memcpy(local_source, source, length); + local_source[length] = '\0'; + break; + case UNICODE_MODE: + error_number = latin1_process(symbol, source, local_source, &length); + if(error_number != 0) { return error_number; } + break; + } + memset(maxi_codeword, 0, sizeof(maxi_codeword)); + + if(mode == -1) { /* If mode is unspecified */ + lp = strlen(symbol->primary); + if(lp == 0) { + mode = 4; + } else { + mode = 2; + for(i = 0; i < 10 && i < lp; i++) { + if((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) { + mode = 3; + break; + } + } + } + } + + if((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */ + strcpy(symbol->errtxt, "Invalid Maxicode Mode"); + return ERROR_INVALID_OPTION; + } + + if((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */ + if(lp != 15) { + strcpy(symbol->errtxt, "Invalid Primary String"); + return ERROR_INVALID_DATA; + } + + for(i = 9; i < 15; i++) { /* check that country code and service are numeric */ + if((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) { + strcpy(symbol->errtxt, "Invalid Primary String"); + return ERROR_INVALID_DATA; + } + } + + memcpy(postcode, symbol->primary, 9); + postcode[9] = '\0'; + + if(mode == 2) { + for(i = 0; i < 10; i++) { + if(postcode[i] == ' ') { + postcode[i] = '\0'; + } + } + } + else if(mode == 3) { postcode[6] = '\0'; } + + countrystr[0] = symbol->primary[9]; + countrystr[1] = symbol->primary[10]; + countrystr[2] = symbol->primary[11]; + countrystr[3] = '\0'; + + servicestr[0] = symbol->primary[12]; + servicestr[1] = symbol->primary[13]; + servicestr[2] = symbol->primary[14]; + servicestr[3] = '\0'; + + countrycode = atoi(countrystr); + service = atoi(servicestr); + + if(mode == 2) { maxi_do_primary_2(postcode, countrycode, service); } + if(mode == 3) { maxi_do_primary_3(postcode, countrycode, service); } + } else { + maxi_codeword[0] = mode; + } + + i = maxi_text_process(mode, local_source, length); + if(i == ERROR_TOO_LONG ) { + strcpy(symbol->errtxt, "Input data too long"); + return i; + } + + /* All the data is sorted - now do error correction */ + maxi_do_primary_check(); /* always EEC */ + + if ( mode == 5 ) + eclen = 56; // 68 data codewords , 56 error corrections + else + eclen = 40; // 84 data codewords, 40 error corrections + + maxi_do_secondary_chk_even(eclen/2); // do error correction of even + maxi_do_secondary_chk_odd(eclen/2); // do error correction of odd + + /* Copy data into symbol grid */ + for(i = 0; i < 33; i++) { + for(j = 0; j < 30; j++) { + block = (MaxiGrid[(i * 30) + j] + 5) / 6; + bit = (MaxiGrid[(i * 30) + j] + 5) % 6; + + if(block != 0) { + + bit_pattern[0] = (maxi_codeword[block - 1] & 0x20) >> 5; + bit_pattern[1] = (maxi_codeword[block - 1] & 0x10) >> 4; + bit_pattern[2] = (maxi_codeword[block - 1] & 0x8) >> 3; + bit_pattern[3] = (maxi_codeword[block - 1] & 0x4) >> 2; + bit_pattern[4] = (maxi_codeword[block - 1] & 0x2) >> 1; + bit_pattern[5] = (maxi_codeword[block - 1] & 0x1); + + if(bit_pattern[bit] != 0) { + set_module(symbol, i, j); + } + } + } + } + + /* Add orientation markings */ + set_module(symbol, 0, 28); // Top right filler + set_module(symbol, 0, 29); + set_module(symbol, 9, 10); // Top left marker + set_module(symbol, 9, 11); + set_module(symbol, 10, 11); + set_module(symbol, 15, 7); // Left hand marker + set_module(symbol, 16, 8); + set_module(symbol, 16, 20); // Right hand marker + set_module(symbol, 17, 20); + set_module(symbol, 22, 10); // Bottom left marker + set_module(symbol, 23, 10); + set_module(symbol, 22, 17); // Bottom right marker + set_module(symbol, 23, 17); + + symbol->width = 30; + symbol->rows = 33; + + return internal_error; +} diff --git a/backend/maxicode.h b/backend/maxicode.h new file mode 100644 index 00000000..f03a902b --- /dev/null +++ b/backend/maxicode.h @@ -0,0 +1,90 @@ +/* maxicode.h - Handles Maxicode */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +static int MaxiGrid[] = { /* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */ /* 30 x 33 data grid */ + 122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0, + 124, 123, 130, 129, 136, 135, 142, 141, 148, 147, 154, 153, 160, 159, 166, 165, 172, 171, 178, 177, 184, 183, 190, 189, 196, 195, 202, 201, 817, 0, + 126, 125, 132, 131, 138, 137, 144, 143, 150, 149, 156, 155, 162, 161, 168, 167, 174, 173, 180, 179, 186, 185, 192, 191, 198, 197, 204, 203, 819, 818, + 284, 283, 278, 277, 272, 271, 266, 265, 260, 259, 254, 253, 248, 247, 242, 241, 236, 235, 230, 229, 224, 223, 218, 217, 212, 211, 206, 205, 820, 0, + 286, 285, 280, 279, 274, 273, 268, 267, 262, 261, 256, 255, 250, 249, 244, 243, 238, 237, 232, 231, 226, 225, 220, 219, 214, 213, 208, 207, 822, 821, + 288, 287, 282, 281, 276, 275, 270, 269, 264, 263, 258, 257, 252, 251, 246, 245, 240, 239, 234, 233, 228, 227, 222, 221, 216, 215, 210, 209, 823, 0, + 290, 289, 296, 295, 302, 301, 308, 307, 314, 313, 320, 319, 326, 325, 332, 331, 338, 337, 344, 343, 350, 349, 356, 355, 362, 361, 368, 367, 825, 824, + 292, 291, 298, 297, 304, 303, 310, 309, 316, 315, 322, 321, 328, 327, 334, 333, 340, 339, 346, 345, 352, 351, 358, 357, 364, 363, 370, 369, 826, 0, + 294, 293, 300, 299, 306, 305, 312, 311, 318, 317, 324, 323, 330, 329, 336, 335, 342, 341, 348, 347, 354, 353, 360, 359, 366, 365, 372, 371, 828, 827, + 410, 409, 404, 403, 398, 397, 392, 391, 80, 79, 0, 0, 14, 13, 38, 37, 3, 0, 45, 44, 110, 109, 386, 385, 380, 379, 374, 373, 829, 0, + 412, 411, 406, 405, 400, 399, 394, 393, 82, 81, 41, 0, 16, 15, 40, 39, 4, 0, 0, 46, 112, 111, 388, 387, 382, 381, 376, 375, 831, 830, + 414, 413, 408, 407, 402, 401, 396, 395, 84, 83, 42, 0, 0, 0, 0, 0, 6, 5, 48, 47, 114, 113, 390, 389, 384, 383, 378, 377, 832, 0, + 416, 415, 422, 421, 428, 427, 104, 103, 56, 55, 17, 0, 0, 0, 0, 0, 0, 0, 21, 20, 86, 85, 434, 433, 440, 439, 446, 445, 834, 833, + 418, 417, 424, 423, 430, 429, 106, 105, 58, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 22, 88, 87, 436, 435, 442, 441, 448, 447, 835, 0, + 420, 419, 426, 425, 432, 431, 108, 107, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 90, 89, 438, 437, 444, 443, 450, 449, 837, 836, + 482, 481, 476, 475, 470, 469, 49, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 53, 464, 463, 458, 457, 452, 451, 838, 0, + 484, 483, 478, 477, 472, 471, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 465, 460, 459, 454, 453, 840, 839, + 486, 485, 480, 479, 474, 473, 52, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 43, 468, 467, 462, 461, 456, 455, 841, 0, + 488, 487, 494, 493, 500, 499, 98, 97, 62, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 92, 91, 506, 505, 512, 511, 518, 517, 843, 842, + 490, 489, 496, 495, 502, 501, 100, 99, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 29, 28, 94, 93, 508, 507, 514, 513, 520, 519, 844, 0, + 492, 491, 498, 497, 504, 503, 102, 101, 66, 65, 18, 0, 0, 0, 0, 0, 0, 0, 19, 30, 96, 95, 510, 509, 516, 515, 522, 521, 846, 845, + 560, 559, 554, 553, 548, 547, 542, 541, 74, 73, 33, 0, 0, 0, 0, 0, 0, 11, 68, 67, 116, 115, 536, 535, 530, 529, 524, 523, 847, 0, + 562, 561, 556, 555, 550, 549, 544, 543, 76, 75, 0, 0, 8, 7, 36, 35, 12, 0, 70, 69, 118, 117, 538, 537, 532, 531, 526, 525, 849, 848, + 564, 563, 558, 557, 552, 551, 546, 545, 78, 77, 0, 34, 10, 9, 26, 25, 0, 0, 72, 71, 120, 119, 540, 539, 534, 533, 528, 527, 850, 0, + 566, 565, 572, 571, 578, 577, 584, 583, 590, 589, 596, 595, 602, 601, 608, 607, 614, 613, 620, 619, 626, 625, 632, 631, 638, 637, 644, 643, 852, 851, + 568, 567, 574, 573, 580, 579, 586, 585, 592, 591, 598, 597, 604, 603, 610, 609, 616, 615, 622, 621, 628, 627, 634, 633, 640, 639, 646, 645, 853, 0, + 570, 569, 576, 575, 582, 581, 588, 587, 594, 593, 600, 599, 606, 605, 612, 611, 618, 617, 624, 623, 630, 629, 636, 635, 642, 641, 648, 647, 855, 854, + 728, 727, 722, 721, 716, 715, 710, 709, 704, 703, 698, 697, 692, 691, 686, 685, 680, 679, 674, 673, 668, 667, 662, 661, 656, 655, 650, 649, 856, 0, + 730, 729, 724, 723, 718, 717, 712, 711, 706, 705, 700, 699, 694, 693, 688, 687, 682, 681, 676, 675, 670, 669, 664, 663, 658, 657, 652, 651, 858, 857, + 732, 731, 726, 725, 720, 719, 714, 713, 708, 707, 702, 701, 696, 695, 690, 689, 684, 683, 678, 677, 672, 671, 666, 665, 660, 659, 654, 653, 859, 0, + 734, 733, 740, 739, 746, 745, 752, 751, 758, 757, 764, 763, 770, 769, 776, 775, 782, 781, 788, 787, 794, 793, 800, 799, 806, 805, 812, 811, 861, 860, + 736, 735, 742, 741, 748, 747, 754, 753, 760, 759, 766, 765, 772, 771, 778, 777, 784, 783, 790, 789, 796, 795, 802, 801, 808, 807, 814, 813, 862, 0, + 738, 737, 744, 743, 750, 749, 756, 755, 762, 761, 768, 767, 774, 773, 780, 779, 786, 785, 792, 791, 798, 797, 804, 803, 810, 809, 816, 815, 864, 863 +}; + +int maxiCodeSet[256] = { /* from Appendix A - ASCII character to Code Set (e.g. 2 = Set B) */ + /* set 0 refers to special characters that fit into more than one set (e.g. GS) */ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 3, 4, 3, 5, 5, 4, 4, 3, 3, 3, + 4, 3, 5, 4, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +int maxiSymbolChar[256] = { /* from Appendix A - ASCII character to symbol value */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 30, 28, 29, 30, 35, 32, 53, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 37, + 38, 39, 40, 41, 52, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 43, 44, 45, 46, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 32, 54, 34, 35, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36, + 37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, 41, 39, 40, 41, + 42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, + 33, 34, 35, 36, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36 +}; + diff --git a/backend/maxipng.h b/backend/maxipng.h new file mode 100644 index 00000000..d7beb6c9 --- /dev/null +++ b/backend/maxipng.h @@ -0,0 +1,138 @@ +/* maxipng.h - Shapes for Maxicode output to PNG file */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* This file contains the pixel-by-pixel representation of maxicode glyphs + at a resolution of 12 pixels per millimeter. hexagon[] is taken directly + from ISO 16023 Annex J. bullseye[] was calculated by the Gimp */ + +#define SSET "0123456789ABCDEF" + +static int hexagon[120] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static unsigned int bullseye_compressed[] = { + 0,0,0,0,0,255,248,0,0,0,0,0, + 0,0,0,0,31,255,255,192,0,0,0,0, + 0,0,0,1,255,255,255,252,0,0,0,0, + 0,0,0,7,255,255,255,255,0,0,0,0, + 0,0,0,31,255,255,255,255,192,0,0,0, + 0,0,0,127,255,255,255,255,240,0,0,0, + 0,0,1,255,255,255,255,255,252,0,0,0, + 0,0,7,255,255,255,255,255,255,0,0,0, + 0,0,15,255,255,0,7,255,255,128,0,0, + 0,0,63,255,240,0,0,127,255,224,0,0, + 0,0,127,255,128,0,0,15,255,240,0,0, + 0,0,255,252,0,0,0,1,255,248,0,0, + 0,1,255,240,0,0,0,0,127,252,0,0, + 0,3,255,224,0,0,0,0,63,254,0,0, + 0,7,255,128,0,0,0,0,15,255,0,0, + 0,15,255,0,0,0,0,0,7,255,128,0, + 0,31,252,0,0,127,240,0,1,255,192,0, + 0,63,248,0,7,255,255,0,0,255,224,0, + 0,127,240,0,63,255,255,224,0,127,240,0, + 0,127,224,0,255,255,255,248,0,63,240,0, + 0,255,192,1,255,255,255,252,0,31,248,0, + 1,255,128,7,255,255,255,255,0,15,252,0, + 1,255,0,15,255,255,255,255,128,7,252,0, + 3,255,0,63,255,255,255,255,224,7,254,0, + 3,254,0,127,255,192,31,255,240,3,254,0, + 7,252,0,255,252,0,1,255,248,1,255,0, + 7,252,1,255,240,0,0,127,252,1,255,0, + 15,248,1,255,192,0,0,31,252,0,255,128, + 15,240,3,255,128,0,0,15,254,0,127,128, + 31,240,7,255,0,0,0,7,255,0,127,192, + 31,224,7,254,0,0,0,3,255,0,63,192, + 63,224,15,252,0,0,0,1,255,128,63,224, + 63,224,31,248,0,63,192,0,255,192,63,224, + 63,192,31,240,0,255,240,0,127,192,31,224, + 63,192,63,224,3,255,252,0,63,224,31,224, + 127,192,63,224,7,255,254,0,63,224,31,240, + 127,128,63,192,15,255,255,0,31,224,15,240, + 127,128,127,192,31,255,255,128,31,240,15,240, + 127,128,127,128,63,255,255,192,15,240,15,240, + 127,128,127,128,63,255,255,192,15,240,15,240, + 255,0,127,128,127,240,255,224,15,240,7,240, + 255,0,255,128,127,192,63,224,15,248,7,240, + 255,0,255,0,255,128,31,240,7,248,7,240, + 255,0,255,0,255,128,31,240,7,248,7,240, + 255,0,255,0,255,0,15,240,7,248,7,240, + 255,0,255,0,255,0,15,240,7,248,7,240, + 255,0,255,0,255,0,15,240,7,248,7,240, + 255,0,255,0,255,0,15,240,7,248,7,240, + 255,0,255,0,255,128,31,240,7,248,7,240, + 255,0,255,0,255,128,31,240,7,248,7,240, + 255,0,255,0,127,192,63,224,7,248,7,240, + 255,0,255,128,127,240,255,224,15,248,7,240, + 255,0,127,128,63,255,255,192,15,240,7,240, + 127,128,127,128,63,255,255,192,15,240,15,240, + 127,128,127,128,31,255,255,128,15,240,15,240, + 127,128,127,192,15,255,255,0,31,240,15,240, + 127,128,63,192,7,255,254,0,31,224,15,240, + 127,192,63,224,3,255,252,0,63,224,31,240, + 63,192,63,224,0,255,240,0,63,224,31,224, + 63,192,31,240,0,63,192,0,127,192,31,224, + 63,224,31,248,0,0,0,0,255,192,63,224, + 63,224,15,252,0,0,0,1,255,128,63,224, + 31,224,7,254,0,0,0,3,255,0,63,192, + 31,240,7,255,0,0,0,7,255,0,127,192, + 15,240,3,255,128,0,0,15,254,0,127,128, + 15,248,1,255,192,0,0,31,252,0,255,128, + 7,252,1,255,240,0,0,127,252,1,255,0, + 7,252,0,255,252,0,1,255,248,1,255,0, + 3,254,0,127,255,192,31,255,240,3,254,0, + 3,255,0,63,255,255,255,255,224,7,254,0, + 1,255,0,15,255,255,255,255,128,7,252,0, + 1,255,128,7,255,255,255,255,0,15,252,0, + 0,255,192,1,255,255,255,252,0,31,248,0, + 0,127,224,0,255,255,255,248,0,63,240,0, + 0,127,240,0,63,255,255,224,0,127,240,0, + 0,63,248,0,7,255,255,0,0,255,224,0, + 0,31,252,0,0,127,240,0,1,255,192,0, + 0,15,255,0,0,0,0,0,7,255,128,0, + 0,7,255,128,0,0,0,0,15,255,0,0, + 0,3,255,224,0,0,0,0,63,254,0,0, + 0,1,255,240,0,0,0,0,127,252,0,0, + 0,0,255,252,0,0,0,1,255,248,0,0, + 0,0,127,255,128,0,0,15,255,240,0,0, + 0,0,63,255,240,0,0,127,255,224,0,0, + 0,0,15,255,255,0,7,255,255,128,0,0, + 0,0,7,255,255,255,255,255,255,0,0,0, + 0,0,1,255,255,255,255,255,252,0,0,0, + 0,0,0,127,255,255,255,255,240,0,0,0, + 0,0,0,31,255,255,255,255,192,0,0,0, + 0,0,0,7,255,255,255,255,0,0,0,0, + 0,0,0,1,255,255,255,252,0,0,0,0, + 0,0,0,0,31,255,255,192,0,0,0,0, + 0,0,0,0,0,255,248,0,0,0,0,0 +}; + diff --git a/backend/medical.c b/backend/medical.c new file mode 100644 index 00000000..ab1a6331 --- /dev/null +++ b/backend/medical.c @@ -0,0 +1,308 @@ +/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include +#include "common.h" + +extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); +/* Codabar table checked against EN 798:1995 */ + +#define CALCIUM "0123456789-$:/.+ABCD" + +static char *CodaTable[20] = {"11111221", "11112211", "11121121", "22111111", "11211211", "21111211", + "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121", + "21212111", "11212121", "11221211", "12121121", "11121221", "11122211"}; + +int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* "Pharmacode can represent only a single integer from 3 to 131070. Unlike other + commonly used one-dimensional barcode schemes, pharmacode does not store the data in a + form corresponding to the human-readable digits; the number is encoded in binary, rather + than decimal. Pharmacode is read from right to left: with n as the bar position starting + at 0 on the right, each narrow bar adds 2n to the value and each wide bar adds 2(2^n). + The minimum barcode is 2 bars and the maximum 16, so the smallest number that could + be encoded is 3 (2 narrow bars) and the biggest is 131070 (16 wide bars)." + - http://en.wikipedia.org/wiki/Pharmacode */ + + /* This code uses the One Track Pharamacode calculating algorithm as recommended by + the specification at http://www.laetus.com/laetus.php?request=file&id=69 */ + + unsigned long int tester; + int counter, error_number, h; + char inter[18] = { 0 }; /* 131070 -> 17 bits */ + char dest[64]; /* 17 * 2 + 1 */ + + error_number = 0; + + if(length > 6) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + tester = atoi((char*)source); + + if((tester < 3) || (tester > 131070)) { + strcpy(symbol->errtxt, "Data out of range"); + return ERROR_INVALID_DATA; + } + + do + { + if(tester % 2 == 0) { + concat(inter, "W"); + tester = (tester - 2) / 2; + } else { + concat(inter, "N"); + tester = (tester - 1) / 2; + } + } + while(tester != 0); + + h = strlen(inter) - 1; + *dest = '\0'; + for(counter = h; counter >= 0; counter--) { + if(inter[counter] == 'W') { + concat(dest, "32"); + } else { + concat(dest, "12"); + } + } + + expand(symbol, dest); + + return error_number; +} + +int pharma_two_calc(struct zint_symbol *symbol, unsigned char source[], char dest[]) +{ + /* This code uses the Two Track Pharamacode defined in the document at + http://www.laetus.com/laetus.php?request=file&id=69 and using a modified + algorithm from the One Track system. This standard accepts integet values + from 4 to 64570080. */ + + unsigned long int tester; + int counter, h; + char inter[17]; + int error_number; + + tester = atoi((char*)source); + + if((tester < 4) || (tester > 64570080)) + { + strcpy(symbol->errtxt, "Data out of range"); + return ERROR_INVALID_DATA; + } + error_number = 0; + strcpy(inter, ""); + do + { + switch(tester%3) { + case 0: + concat(inter, "3"); + tester = (tester - 3) / 3; + break; + case 1: + concat(inter, "1"); + tester = (tester - 1) / 3; + break; + case 2: + concat(inter, "2"); + tester = (tester - 2) / 3; + break; + } + } + while(tester != 0); + + h = strlen(inter) - 1; + for(counter = h; counter >= 0; counter--) + { + dest[h - counter] = inter[counter]; + } + dest[h + 1] = '\0'; + + return error_number; +} + +int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Draws the patterns for two track pharmacode */ + char height_pattern[200]; + unsigned int loopey, h; + int writer; + int error_number = 0; + strcpy(height_pattern, ""); + + if(length > 8) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + error_number = pharma_two_calc(symbol, source, height_pattern); + if(error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '3')) + { + set_module(symbol, 0, writer); + } + if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '3')) + { + set_module(symbol, 1, writer); + } + writer += 2; + } + symbol->rows = 2; + symbol->width = writer - 1; + + + return error_number; +} + +int codabar(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* The Codabar system consisting of simple substitution */ + + int i, error_number; + char dest[512]; + + error_number = 0; + strcpy(dest, ""); + + if(length > 60) { /* No stack smashing please */ + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(CALCIUM, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + /* Codabar must begin and end with the characters A, B, C or D */ + if((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C') && (source[0] != 'D')) + { + strcpy(symbol->errtxt, "Invalid characters in data"); + return ERROR_INVALID_DATA; + } + + if((source[length - 1] != 'A') && (source[length - 1] != 'B') && + (source[length - 1] != 'C') && (source[length - 1] != 'D')) + { + strcpy(symbol->errtxt, "Invalid characters in data"); + return ERROR_INVALID_DATA; + } + + for(i = 0; i < length; i++) + { + lookup(CALCIUM, CodaTable, source[i], dest); + } + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +int code32(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Italian Pharmacode */ + int i, zeroes, error_number, checksum, checkpart, checkdigit; + char localstr[10], risultante[7]; + long int pharmacode, remainder, devisor; + int codeword[6]; + char tabella[34]; + + /* Validate the input */ + if(length > 8) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* Add leading zeros as required */ + zeroes = 8 - length; + memset(localstr, '0', zeroes); + strcpy(localstr + zeroes, (char*)source); + + /* Calculate the check digit */ + checksum = 0; + checkpart = 0; + for(i = 0; i < 4; i++) { + checkpart = ctoi(localstr[i * 2]); + checksum += checkpart; + checkpart = 2 * (ctoi(localstr[(i * 2) + 1])); + if(checkpart >= 10) { + checksum += (checkpart - 10) + 1; + } else { + checksum += checkpart; + } + } + + /* Add check digit to data string */ + checkdigit = checksum % 10; + localstr[8] = itoc(checkdigit); + localstr[9] = '\0'; + + /* Convert string into an integer value */ + pharmacode = atoi(localstr); + + /* Convert from decimal to base-32 */ + devisor = 33554432; + for(i = 5; i >= 0; i--) { + codeword[i] = pharmacode / devisor; + remainder = pharmacode % devisor; + pharmacode = remainder; + devisor /= 32; + } + + /* Look up values in 'Tabella di conversione' */ + strcpy(tabella, "0123456789BCDFGHJKLMNPQRSTUVWXYZ"); + for(i = 5; i >= 0; i--) { + risultante[5 - i] = tabella[codeword[i]]; + } + risultante[6] = '\0'; + /* Plot the barcode using Code 39 */ + error_number = c39(symbol, (unsigned char*)risultante, strlen(risultante)); + if(error_number != 0) { return error_number; } + + /* Override the normal text output with the Pharmacode number */ + ustrcpy(symbol->text, (unsigned char*)"A"); + uconcat(symbol->text, (unsigned char*)localstr); + + return error_number; +} diff --git a/backend/ms_stdint.h b/backend/ms_stdint.h new file mode 100644 index 00000000..76987ab6 --- /dev/null +++ b/backend/ms_stdint.h @@ -0,0 +1,234 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// 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. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +// +/////////////////////////////////////////////////////////////////////////////// + +/* @(#) $Id: ms_stdint.h,v 1.1 2009/09/19 08:16:21 hooper114 Exp $ */ + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if (_MSC_VER < 1300) && defined(__cplusplus) + extern "C++" { +#endif +# include +#if (_MSC_VER < 1300) && defined(__cplusplus) + } +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/backend/pdf417.c b/backend/pdf417.c new file mode 100644 index 00000000..99c7996c --- /dev/null +++ b/backend/pdf417.c @@ -0,0 +1,1083 @@ +/* pdf417.c - Handles PDF417 stacked symbology */ + +/* Zint - A barcode generating program using libpng + Copyright (C) 2008 Robin Stuart + Portions Copyright (C) 2004 Grandzebu + Bug Fixes thanks to KL Chin + + 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. +*/ + +/* This code is adapted from "Code barre PDF 417 / PDF 417 barcode" v2.5.0 + which is Copyright (C) 2004 (Grandzebu). + The original code can be downloaded from http://grandzebu.net/index.php */ + +/* NOTE: symbol->option_1 is used to specify the security level (i.e. control the + number of check codewords) + + symbol->option_2 is used to adjust the width of the resulting symbol (i.e. the + number of codeword columns not including row start and end data) */ + +/* @(#) $Id: pdf417.c,v 1.21 2010/01/28 17:55:59 hooper114 Exp $ */ + +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#else +#include +#include "ms_stdint.h" +#endif +#include "pdf417.h" +#include "common.h" +#include "large.h" + +/* + Three figure numbers in comments give the location of command equivalents in the + original Visual Basic source code file pdf417.frm + this code retains some original (French) procedure and variable names to ease conversion */ + +/* text mode processing tables */ + +static int asciix[95] = { 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 12, 8, 8, 4, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 8, 8, 8, 8 }; + +static int asciiy[95] = { 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4, 5, 6, 24, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 21, 27, 9 }; + +/* Automatic sizing table */ + +static int MicroAutosize[56] = +{ 4, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19, 20, 24, 29, 30, 33, 34, 37, 39, 46, 54, 58, 70, 72, 82, 90, 108, 126, + 1, 14, 2, 7, 3, 25, 8, 16, 5, 17, 9, 6, 10, 11, 28, 12, 19, 13, 29, 20, 30, 21, 22, 31, 23, 32, 33, 34 +}; + +int liste[2][1000]; /* global - okay, so I got _almost_ everything local! */ + +/* 866 */ + +int quelmode(char codeascii) +{ + int mode = BYT; + if ((codeascii == '\t') || (codeascii == '\n') || (codeascii == '\r') || ((codeascii >= ' ') && (codeascii <= '~'))) { mode = TEX; } + else if((codeascii >= '0') && (codeascii <= '9')) { mode = NUM; } + /* 876 */ + + return mode; +} + +/* 844 */ +void regroupe(int *indexliste) +{ + int i, j; + + /* bring together same type blocks */ + if(*(indexliste) > 1) { + i = 1; + while(i < *(indexliste)) { + if(liste[1][i - 1] == liste[1][i]) { + /* bring together */ + liste[0][i - 1] = liste[0][i - 1] + liste[0][i]; + j = i + 1; + + /* decreace the list */ + while(j < *(indexliste)) { + liste[0][j - 1] = liste[0][j]; + liste[1][j - 1] = liste[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } + /* 865 */ +} + +/* 478 */ +void pdfsmooth(int *indexliste) +{ + int i, crnt, last, next, length; + + for(i = 0; i < *(indexliste); i++) { + crnt = liste[1][i]; + length = liste[0][i]; + if(i != 0) { last = liste[1][i - 1]; } else { last = FALSE; } + if(i != *(indexliste) - 1) { next = liste[1][i + 1]; } else { next = FALSE; } + + if(crnt == NUM) { + if(i == 0) { /* first block */ + if(*(indexliste) > 1) { /* and there are others */ + if((next == TEX) && (length < 8)) { liste[1][i] = TEX;} + if((next == BYT) && (length == 1)) { liste[1][i] = BYT; } + } + } else { + if(i == *(indexliste) - 1) { /* last block */ + if((last == TEX) && (length < 7)) { liste[1][i] = TEX; } + if((last == BYT) && (length == 1)) { liste[1][i] = BYT; } + } else { /* not first or last block */ + if(((last == BYT) && (next == BYT)) && (length < 4)) { liste[1][i] = BYT; } + if(((last == BYT) && (next == TEX)) && (length < 4)) { liste[1][i] = TEX; } + if(((last == TEX) && (next == BYT)) && (length < 5)) { liste[1][i] = TEX; } + if(((last == TEX) && (next == TEX)) && (length < 8)) { liste[1][i] = TEX; } + } + } + } + } + regroupe(indexliste); + /* 520 */ + for(i = 0; i < *(indexliste); i++) { + crnt = liste[1][i]; + length = liste[0][i]; + if(i != 0) { last = liste[1][i - 1]; } else { last = FALSE; } + if(i != *(indexliste) - 1) { next = liste[1][i + 1]; } else { next = FALSE; } + + if((crnt == TEX) && (i > 0)) { /* not the first */ + if(i == *(indexliste) - 1) { /* the last one */ + if((last == BYT) && (length == 1)) { liste[1][i] = BYT; } + } else { /* not the last one */ + if(((last == BYT) && (next == BYT)) && (length < 5)) { liste[1][i] = BYT; } + if((((last == BYT) && (next != BYT)) || ((last != BYT) && (next == BYT))) && (length < 3)) { + liste[1][i] = BYT; + } + } + } + } + /* 540 */ + regroupe(indexliste); +} + +/* 547 */ +void textprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) +{ + int j, indexlistet, curtable, listet[2][5000], chainet[5000], wnet; + char codeascii; + + codeascii = 0; + wnet = 0; + + for(j = 0; j < 1000; j++) { + listet[0][j] = 0; + } + /* listet will contain the table numbers and the value of each characters */ + for(indexlistet = 0; indexlistet < length; indexlistet++) { + codeascii = chaine[start + indexlistet]; + switch(codeascii) { + case '\t': listet[0][indexlistet] = 12; listet[1][indexlistet] = 12; break; + case '\n': listet[0][indexlistet] = 8; listet[1][indexlistet] = 15; break; + case 13: listet[0][indexlistet] = 12; listet[1][indexlistet] = 11; break; + default: listet[0][indexlistet] = asciix[codeascii - 32]; + listet[1][indexlistet] = asciiy[codeascii - 32]; break; + } + } + + /* 570 */ + curtable = 1; /* default table */ + for(j = 0; j < length; j++) { + if(listet[0][j] & curtable) { /* The character is in the current table */ + chainet[wnet] = listet[1][j]; + wnet++; + } else { /* Obliged to change table */ + int flag = FALSE; /* True if we change table for only one character */ + if (j == (length - 1)) { + flag = TRUE; + } else { + if(!(listet[0][j] & listet[0][j + 1])) { flag = TRUE; } + } + + if (flag) { /* we change only one character - look for temporary switch */ + if((listet[0][j] & 1) && (curtable == 2)) { /* T_UPP */ + chainet[wnet] = 27; + chainet[wnet + 1] = listet[1][j]; + wnet += 2; + } + if(listet[0][j] & 8) { /* T_PUN */ + chainet[wnet] = 29; + chainet[wnet + 1] = listet[1][j]; + wnet += 2; + } + if(!(((listet[0][j] & 1) && (curtable == 2)) || (listet[0][j] & 8))) { + /* No temporary switch available */ + flag = FALSE; + } + } + + /* 599 */ + if (!(flag)) { + int newtable; + + if(j == (length - 1)) { + newtable = listet[0][j]; + } else { + if(!(listet[0][j] & listet[0][j + 1])) { + newtable = listet[0][j]; + } else { + newtable = listet[0][j] & listet[0][j + 1]; + } + } + + /* Maintain the first if several tables are possible */ + switch (newtable) { + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + case 15: + newtable = 1; break; + case 6: + case 10: + case 14: + newtable = 2; break; + case 12: + newtable = 4; break; + } + + /* 619 - select the switch */ + switch (curtable) { + case 1: + switch (newtable) { + case 2: chainet[wnet] = 27; wnet++; break; + case 4: chainet[wnet] = 28; wnet++; break; + case 8: chainet[wnet] = 28; wnet++; chainet[wnet] = 25; wnet++; break; + } break; + case 2: + switch (newtable) { + case 1: chainet[wnet] = 28; wnet++; chainet[wnet] = 28; wnet++; break; + case 4: chainet[wnet] = 28; wnet++; break; + case 8: chainet[wnet] = 28; wnet++; chainet[wnet] = 25; wnet++; break; + } break; + case 4: + switch (newtable) { + case 1: chainet[wnet] = 28; wnet++; break; + case 2: chainet[wnet] = 27; wnet++; break; + case 8: chainet[wnet] = 25; wnet++; break; + } break; + case 8: + switch (newtable) { + case 1: chainet[wnet] = 29; wnet++; break; + case 2: chainet[wnet] = 29; wnet++; chainet[wnet] = 27; wnet++; break; + case 4: chainet[wnet] = 29; wnet++; chainet[wnet] = 28; wnet++; break; + } break; + } + curtable = newtable; + /* 659 - at last we add the character */ + chainet[wnet] = listet[1][j]; + wnet++; + } + } + } + + /* 663 */ + if ((wnet % 2) > 0) { + chainet[wnet] = 29; + wnet++; + } + /* Now translate the string chainet into codewords */ + chainemc[*(mclength)] = 900; + *(mclength) = *(mclength) + 1; + + for(j = 0; j < wnet; j+= 2) { + int cw_number; + + cw_number = (30 * chainet[j]) + chainet[j + 1]; + chainemc[*(mclength)] = cw_number; + *(mclength) = *(mclength) + 1; + + } +} + +/* 671 */ +void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block) +{ + int debug = 0; + int len = 0; + unsigned int chunkLen = 0; + uint64_t mantisa = 0ULL; + uint64_t total = 0ULL; + + if(debug) printf("\nEntering byte mode at position %d\n", start); + + if(length == 1) { + chainemc[(*mclength)++] = 913; + chainemc[(*mclength)++] = chaine[start]; + if(debug) { printf("913 %d\n", chainemc[*mclength - 1]); } + } else { + /* select the switch for multiple of 6 bytes */ + if (length % 6 == 0) { + chainemc[(*mclength)++] = 924; + if(debug) printf("924 "); + } else { + chainemc[(*mclength)++] = 901; + if(debug) printf("901 "); + } + + while (len < length) + { + chunkLen = length - len; + if (6 <= chunkLen) /* Take groups of 6 */ + { + chunkLen = 6; + len += chunkLen; + total = 0ULL; + + while (chunkLen--) + { + mantisa = chaine[start++]; + total |= mantisa << (uint64_t)(chunkLen * 8ULL); + } + + chunkLen = 5; + + while (chunkLen--) + { + chainemc[*mclength + chunkLen] = (int)(total % 900ULL); + total /= 900ULL; + } + *mclength += 5; + } + else /* If it remain a group of less than 6 bytes */ + { + len += chunkLen; + while (chunkLen--) + { + chainemc[(*mclength)++] = chaine[start++]; + } + } + } + } +} + +/* 712 */ +void numbprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) +{ + int j, loop, longueur, dummy[100], dumlength, diviseur, nombre; + char chainemod[50], chainemult[100], temp; + + strcpy(chainemod, ""); + for(loop = 0; loop <= 50; loop++) { + dummy[loop] = 0; + } + + chainemc[*(mclength)] = 902; + *(mclength) = *(mclength) + 1; + + j = 0; + while(j < length) { + dumlength = 0; + strcpy(chainemod, ""); + longueur = length - j; + if(longueur > 44) { longueur = 44; } + concat(chainemod, "1"); + for(loop = 1; loop <= longueur; loop++) { + chainemod[loop] = chaine[start + loop + j - 1]; + } + chainemod[longueur + 1] = '\0'; + do { + diviseur = 900; + + /* 877 - gosub Modulo */ + strcpy(chainemult, ""); + nombre = 0; + while(strlen(chainemod) != 0) { + nombre *= 10; + nombre += ctoi(chainemod[0]); + for(loop = 0; loop < strlen(chainemod); loop++) { + chainemod[loop] = chainemod[loop + 1]; + } + if (nombre < diviseur) { + if (strlen(chainemult) != 0) { concat(chainemult, "0"); } + } else { + temp = (nombre / diviseur) + '0'; + chainemult[strlen(chainemult) + 1] = '\0'; + chainemult[strlen(chainemult)] = temp; + } + nombre = nombre % diviseur; + } + diviseur = nombre; + /* return to 723 */ + + for(loop = dumlength; loop > 0; loop--) { + dummy[loop] = dummy[loop - 1]; + } + dummy[0] = diviseur; + dumlength++; + strcpy(chainemod, chainemult); + } while(strlen(chainemult) != 0); + for(loop = 0; loop < dumlength; loop++) { + chainemc[*(mclength)] = dummy[loop]; + *(mclength) = *(mclength) + 1; + } + j += longueur; + } +} + +/* 366 */ +int pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) +{ + int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520], offset; + int total, chainemc[2700], mclength, c1, c2, c3, dummy[35], codeerr; + char codebarre[100], pattern[580]; + int debug = 0; + + codeerr = 0; + + /* 456 */ + indexliste = 0; + indexchaine = 0; + + mode = quelmode(chaine[indexchaine]); + + for(i = 0; i < 1000; i++) { + liste[0][i] = 0; + } + + /* 463 */ + do { + liste[1][indexliste] = mode; + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { + liste[0][indexliste]++; + indexchaine++; + mode = quelmode(chaine[indexchaine]); + } + indexliste++; + } while (indexchaine < length); + + /* 474 */ + pdfsmooth(&indexliste); + + if(debug) { + printf("Initial block pattern:\n"); + for(i = 0; i < indexliste; i++) { + printf("Len: %d Type: ", liste[0][i]); + switch(liste[1][i]) { + case TEX: printf("Text\n"); break; + case BYT: printf("Byte\n"); break; + case NUM: printf("Number\n"); break; + default: printf("ERROR\n"); break; + } + } + } + + /* 541 - now compress the data */ + indexchaine = 0; + mclength = 0; + if(symbol->output_options & READER_INIT) { + chainemc[mclength] = 921; /* Reader Initialisation */ + mclength++; + } + for(i = 0; i < indexliste; i++) { + switch(liste[1][i]) { + case TEX: /* 547 - text mode */ + textprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); + break; + case BYT: /* 670 - octet stream mode */ + byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); + break; + case NUM: /* 712 - numeric mode */ + numbprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); + break; + } + indexchaine = indexchaine + liste[0][i]; + } + + if(debug) { + printf("\nCompressed data stream:\n"); + for(i = 0; i < mclength; i++) { + printf("%d ", chainemc[i]); + } + printf("\n\n"); + } + + /* 752 - Now take care of the number of CWs per row */ + if (symbol->option_1 < 0) { + /* note that security level 8 is never used automatically */ + symbol->option_1 = 7; + if(mclength <= 1280) { symbol->option_1 = 6; } + if(mclength <= 640) { symbol->option_1 = 5; } + if(mclength <= 320) { symbol->option_1 = 4; } + if(mclength <= 160) { symbol->option_1 = 3; } + if(mclength <= 40) { symbol->option_1 = 2; } + } + k = 1; + for(loop = 1; loop <= (symbol->option_1 + 1); loop++) + { + k *= 2; + } + longueur = mclength; + if(symbol->option_2 > 30) { symbol->option_2 = 30; } + if(symbol->option_2 < 1) { + /* This is a much more simple formula to Grand Zebu's - + it does not try to make the symbol square */ + symbol->option_2 = 0.5 + sqrt((longueur + k) / 3.0); + } + if(((longueur + k) / symbol->option_2) > 90) { + /* stop the symbol from becoming too high */ + symbol->option_2 = symbol->option_2 + 1; + } + + /* Reduce the correction level if there isn't room */ + /* while((longueur + k > PDF_MAX) && (symbol->option_1 > 0)) { + symbol->option_1 = symbol->option_1 - 1 + for(loop = 0; loop <= (symbol->option_1 + 1); loop++) + { + k *= 2; + } + } */ + /* this bit of the code would allow Zint to happily encode 2698 code words with + only 2 check digits, so I have abandoned it! - Zint now insists on a proportional + amount of check data unless overruled by the user */ + + if(longueur + k > symbol->option_3) { + return 2; + } + if(((longueur + k) / symbol->option_2) > 90) { + return 4; + } + + /* 781 - Padding calculation */ + longueur = mclength + 1 + k; + i = 0; + if ((longueur / symbol->option_2) < 3) { + i = (symbol->option_2 * 3) - longueur; /* A bar code must have at least three rows */ + } else { + if((longueur % symbol->option_2) > 0) { i = symbol->option_2 - (longueur % symbol->option_2); } + } + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + /* we add the length descriptor */ + for(i = mclength; i > 0; i--) { + chainemc[i] = chainemc[i - 1]; + } + chainemc[0] = mclength + 1; + mclength++; + + /* 796 - we now take care of the Reed Solomon codes */ + switch(symbol->option_1) { + case 1: offset = 2; break; + case 2: offset = 6; break; + case 3: offset = 14; break; + case 4: offset = 30; break; + case 5: offset = 62; break; + case 6: offset = 126; break; + case 7: offset = 254; break; + case 8: offset = 510; break; + default: offset = 0; break; + } + + longueur = mclength; + for(loop = 0; loop < 520; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for(i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for(j = k - 1; j > 0; j--) { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; + } + mccorrection[0] = (929 - (total * coefrs[offset + j]) % 929) % 929; + } + + /* we add these codes to the string */ + for(i = k - 1; i >= 0; i--) { + chainemc[mclength++] = mccorrection[i] ? 929 - mccorrection[i] : 0; + } + + /* 818 - The CW string is finished */ + c1 = (mclength / symbol->option_2 - 1) / 3; + c2 = symbol->option_1 * 3 + (mclength / symbol->option_2 - 1) % 3; + c3 = symbol->option_2 - 1; + + /* we now encode each row */ + for(i = 0; i <= (mclength / symbol->option_2) - 1; i++) { + for(j = 0; j < symbol->option_2 ; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + } + k = (i / 3) * 30; + switch(i % 3) { + /* follows this pattern from US Patent 5,243,655: + Row 0: L0 (row #, # of rows) R0 (row #, # of columns) + Row 1: L1 (row #, security level) R1 (row #, # of rows) + Row 2: L2 (row #, # of columns) R2 (row #, security level) + Row 3: L3 (row #, # of rows) R3 (row #, # of columns) + etc. */ + case 0: + dummy[0] = k + c1; + dummy[symbol->option_2 + 1] = k + c3; + break; + case 1: + dummy[0] = k + c2; + dummy[symbol->option_2 + 1] = k + c1; + break; + case 2: + dummy[0] = k + c3; + dummy[symbol->option_2 + 1] = k + c2; + break; + } + strcpy(codebarre, "+*"); /* Start with a start char and a separator */ + if(symbol->symbology == BARCODE_PDF417TRUNC) { + /* truncated - so same as before except knock off the last 5 chars */ + for(j = 0; j <= symbol->option_2; j++) { + switch(i % 3) { + case 1: offset = 929; break; + case 2: offset = 1858; break; + default: offset = 0; break; + } + concat(codebarre, codagemc[offset + dummy[j]]); + concat(codebarre, "*"); + } + } else { + /* normal PDF417 symbol */ + for(j = 0; j <= symbol->option_2 + 1; j++) { + switch(i % 3) { + case 1: offset = 929; /* cluster(3) */ break; + case 2: offset = 1858; /* cluster(6) */ break; + default: offset = 0; /* cluster(0) */ break; + } + concat(codebarre, codagemc[offset + dummy[j]]); + concat(codebarre, "*"); + } + concat(codebarre, "-"); + } + + strcpy(pattern, ""); + for(loop = 0; loop < strlen(codebarre); loop++) { + lookup(BRSET, PDFttf, codebarre[loop], pattern); + } + for(loop = 0; loop < strlen(pattern); loop++) { + if(pattern[loop] == '1') { set_module(symbol, i, loop); } + } + if(symbol->height == 0) { + symbol->row_height[i] = 3; + } + } + symbol->rows = (mclength / symbol->option_2); + symbol->width = strlen(pattern); + + /* 843 */ + return codeerr; +} + +/* 345 */ +int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int codeerr, error_number; + + error_number = 0; + + if((symbol->option_1 < -1) || (symbol->option_1 > 8)) { + strcpy(symbol->errtxt, "Security value out of range"); + symbol->option_1 = -1; + error_number = WARN_INVALID_OPTION; + } + if((symbol->option_2 < 0) || (symbol->option_2 > 30)) { + strcpy(symbol->errtxt, "Number of columns out of range"); + symbol->option_2 = 0; + error_number = WARN_INVALID_OPTION; + } + + /* 349 */ + codeerr = pdf417(symbol, source, length); + + /* 352 */ + if(codeerr != 0) { + switch(codeerr) { + case 1: + strcpy(symbol->errtxt, "No such file or file unreadable"); + error_number = ERROR_INVALID_OPTION; + break; + case 2: + strcpy(symbol->errtxt, "Input string too long"); + error_number = ERROR_TOO_LONG; + break; + case 3: + strcpy(symbol->errtxt, "Number of codewords per row too small"); + error_number = WARN_INVALID_OPTION; + break; + case 4: + strcpy(symbol->errtxt, "Data too long for specified number of columns"); + error_number = ERROR_TOO_LONG; + break; + default: + strcpy(symbol->errtxt, "Something strange happened"); + error_number = ERROR_ENCODING_PROBLEM; + break; + } + } + + /* 364 */ + return error_number; +} + + +int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) +{ /* like PDF417 only much smaller! */ + + int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50], offset; + int total, chainemc[2700], mclength, dummy[5], codeerr; + char codebarre[100], pattern[580]; + int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; + int LeftRAP, CentreRAP, RightRAP, Cluster, writer, flip, loop; + int debug = 0; + + /* Encoding starts out the same as PDF417, so use the same code */ + codeerr = 0; + + /* 456 */ + indexliste = 0; + indexchaine = 0; + + mode = quelmode(chaine[indexchaine]); + + for(i = 0; i < 1000; i++) { + liste[0][i] = 0; + } + + /* 463 */ + do { + liste[1][indexliste] = mode; + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { + liste[0][indexliste]++; + indexchaine++; + mode = quelmode(chaine[indexchaine]); + } + indexliste++; + } while (indexchaine < length); + + /* 474 */ + pdfsmooth(&indexliste); + + if(debug) { + printf("Initial mapping:\n"); + for(i = 0; i < indexliste; i++) { + printf("len: %d type: ", liste[0][i]); + switch(liste[1][i]) { + case TEX: printf("TEXT\n"); break; + case BYT: printf("BYTE\n"); break; + case NUM: printf("NUMBER\n"); break; + default: printf("*ERROR*\n"); break; + } + } + } + + /* 541 - now compress the data */ + indexchaine = 0; + mclength = 0; + if(symbol->output_options & READER_INIT) { + chainemc[mclength] = 921; /* Reader Initialisation */ + mclength++; + } + for(i = 0; i < indexliste; i++) { + switch(liste[1][i]) { + case TEX: /* 547 - text mode */ + textprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); + break; + case BYT: /* 670 - octet stream mode */ + byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); + break; + case NUM: /* 712 - numeric mode */ + numbprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); + break; + } + indexchaine = indexchaine + liste[0][i]; + } + + /* This is where it all changes! */ + + if(mclength > 126) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + if(symbol->option_2 > 4) { + strcpy(symbol->errtxt, "Specified width out of range"); + symbol->option_2 = 0; + codeerr = WARN_INVALID_OPTION; + } + + if(debug) { + printf("\nEncoded Data Stream:\n"); + for(i = 0; i < mclength; i++) { + printf("0x%02X ", chainemc[i]); + } + printf("\n"); + } + + /* Now figure out which variant of the symbol to use and load values accordingly */ + + variant = 0; + + if((symbol->option_2 == 1) && (mclength > 20)) { + /* the user specified 1 column but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "Specified symbol size too small for data"); + codeerr = WARN_INVALID_OPTION; + } + + if((symbol->option_2 == 2) && (mclength > 37)) { + /* the user specified 2 columns but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "Specified symbol size too small for data"); + codeerr = WARN_INVALID_OPTION; + } + + if((symbol->option_2 == 3) && (mclength > 82)) { + /* the user specified 3 columns but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "Specified symbol size too small for data"); + codeerr = WARN_INVALID_OPTION; + } + + if(symbol->option_2 == 1) { + /* the user specified 1 column and the data does fit */ + variant = 6; + if(mclength <= 16) { variant = 5; } + if(mclength <= 12) { variant = 4; } + if(mclength <= 10) { variant = 3; } + if(mclength <= 7) { variant = 2; } + if(mclength <= 4) { variant = 1; } + } + + if(symbol->option_2 == 2) { + /* the user specified 2 columns and the data does fit */ + variant = 13; + if(mclength <= 33) { variant = 12; } + if(mclength <= 29) { variant = 11; } + if(mclength <= 24) { variant = 10; } + if(mclength <= 19) { variant = 9; } + if(mclength <= 13) { variant = 8; } + if(mclength <= 8) { variant = 7; } + } + + if(symbol->option_2 == 3) { + /* the user specified 3 columns and the data does fit */ + variant = 23; + if(mclength <= 70) { variant = 22; } + if(mclength <= 58) { variant = 21; } + if(mclength <= 46) { variant = 20; } + if(mclength <= 34) { variant = 19; } + if(mclength <= 24) { variant = 18; } + if(mclength <= 18) { variant = 17; } + if(mclength <= 14) { variant = 16; } + if(mclength <= 10) { variant = 15; } + if(mclength <= 6) { variant = 14; } + } + + if(symbol->option_2 == 4) { + /* the user specified 4 columns and the data does fit */ + variant = 34; + if(mclength <= 108) { variant = 33; } + if(mclength <= 90) { variant = 32; } + if(mclength <= 72) { variant = 31; } + if(mclength <= 54) { variant = 30; } + if(mclength <= 39) { variant = 29; } + if(mclength <= 30) { variant = 28; } + if(mclength <= 24) { variant = 27; } + if(mclength <= 18) { variant = 26; } + if(mclength <= 12) { variant = 25; } + if(mclength <= 8) { variant = 24; } + } + + if(variant == 0) { + /* Zint can choose automatically from all available variations */ + for(i = 27; i >= 0; i--) { + + if(MicroAutosize[i] >= mclength) { + variant = MicroAutosize[i + 28]; + } + } + } + + /* Now we have the variant we can load the data */ + variant --; + symbol->option_2 = MicroVariants[variant]; /* columns */ + symbol->rows = MicroVariants[variant + 34]; /* rows */ + k = MicroVariants[variant + 68]; /* number of EC CWs */ + longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ + i = longueur - mclength; /* amount of padding required */ + offset = MicroVariants[variant + 102]; /* coefficient offset */ + + if(debug) { + printf("\nChoose symbol size:\n"); + printf("%d columns x %d rows\n", symbol->option_2, symbol->rows); + printf("%d data codewords (including %d pads), %d ecc codewords\n", longueur, i, k); + printf("\n"); + } + + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + + /* Reed-Solomon error correction */ + longueur = mclength; + for(loop = 0; loop < 50; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for(i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for(j = k - 1; j >= 0; j--) { + if(j == 0) { + mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } + } + } + + for(j = 0; j < k; j++) { + if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } + } + /* we add these codes to the string */ + for(i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + if(debug) { + printf("Encoded Data Stream with ECC:\n"); + for(i = 0; i < mclength; i++) { + printf("0x%02X ", chainemc[i]); + } + printf("\n"); + } + + /* Now get the RAP (Row Address Pattern) start values */ + LeftRAPStart = RAPTable[variant]; + CentreRAPStart = RAPTable[variant + 34]; + RightRAPStart = RAPTable[variant + 68]; + StartCluster = RAPTable[variant + 102] / 3; + + /* That's all values loaded, get on with the encoding */ + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + if(debug) printf("\nInternal row representation:\n"); + for(i = 0; i < symbol->rows; i++) { + if(debug) printf("row %d: ", i); + strcpy(codebarre, ""); + offset = 929 * Cluster; + for(j = 0; j < 5; j++) { + dummy[j] = 0; + } + for(j = 0; j < symbol->option_2 ; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + if(debug) printf("[%d] ", dummy[j + 1]); + } + + /* Copy the data into codebarre */ + concat(codebarre, RAPLR[LeftRAP]); + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[1]]); + concat(codebarre, "1"); + if(symbol->option_2 == 3) { + concat(codebarre, RAPC[CentreRAP]); + } + if(symbol->option_2 >= 2) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[2]]); + concat(codebarre, "1"); + } + if(symbol->option_2 == 4) { + concat(codebarre, RAPC[CentreRAP]); + } + if(symbol->option_2 >= 3) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[3]]); + concat(codebarre, "1"); + } + if(symbol->option_2 == 4) { + concat(codebarre, "1"); + concat(codebarre, codagemc[offset + dummy[4]]); + concat(codebarre, "1"); + } + concat(codebarre, RAPLR[RightRAP]); + concat(codebarre, "1"); /* stop */ + if(debug) printf("%s\n", codebarre); + + /* Now codebarre is a mixture of letters and numbers */ + + writer = 0; + flip = 1; + strcpy(pattern, ""); + for(loop = 0; loop < strlen(codebarre); loop++) { + if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { + for(k = 0; k < ctoi(codebarre[loop]); k++) { + if(flip == 0) { + pattern[writer] = '0'; + } else { + pattern[writer] = '1'; + } + writer++; + } + pattern[writer] = '\0'; + if(flip == 0) { + flip = 1; + } else { + flip = 0; + } + } else { + lookup(BRSET, PDFttf, codebarre[loop], pattern); + writer += 5; + } + } + symbol->width = writer; + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for(loop = 0; loop < strlen(pattern); loop++) { + if(pattern[loop] == '1') { set_module(symbol, i, loop); } + } + symbol->row_height[i] = 2; + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if(LeftRAP == 53) { + LeftRAP = 1; + } + if(CentreRAP == 53) { + CentreRAP = 1; + } + if(RightRAP == 53) { + RightRAP = 1; + } + if(Cluster == 3) { + Cluster = 0; + } + } + + return codeerr; +} + diff --git a/backend/pdf417.h b/backend/pdf417.h new file mode 100644 index 00000000..4e65ecf2 --- /dev/null +++ b/backend/pdf417.h @@ -0,0 +1,438 @@ +/* pdf417.h - PDF417 tables and coefficients */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + Portions Copyright (C) 2004 Grandzebu + + 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. +*/ + +/* this file contains the character table, the pre-calculated coefficients and the + codeword patterns taken from lines 416 to 454 of pdf417.frm */ + +#define TRUE 1 +#define FALSE 0 +#define TEX 900 +#define BYT 901 +#define NUM 902 + +#define BRSET "ABCDEFabcdefghijklmnopqrstuvwxyz*+-" + +/* PDF417 error correction coefficients from Grand Zebu */ +static int coefrs[1022] = { + /* k = 2 */ + 27, 917, + + /* k = 4 */ + 522, 568, 723, 809, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379, + + /* k = 16 */ + 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, + + /* k = 32 */ + 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, + 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, + + /* k = 64 */ + 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, + 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, + 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, + 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543, + + /* k = 128 */ + 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, + 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, + 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, + 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, + 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, + 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, + 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, + 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539, + + /* k = 256 */ + 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, + 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, + 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, + 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, + 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, + 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, + 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, + 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, + 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, + 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, + 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, + 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, + 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, + 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, + 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, + 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10, + + /* k = 512 */ + 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, + 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, + 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, + 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, + 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, + 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, + 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, + 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, + 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, + 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, + 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, + 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, + 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, + 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, + 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, + 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, + 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, + 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, + 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, + 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, + 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, + 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, + 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, + 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, + 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, + 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, + 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, + 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, + 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, + 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, + 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, + 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 }; + + +static char *codagemc[2787] = { "urA", "xfs", "ypy", "unk", "xdw", "yoz", "pDA", "uls", "pBk", "eBA", + "pAs", "eAk", "prA", "uvs", "xhy", "pnk", "utw", "xgz", "fDA", "pls", "fBk", "frA", "pvs", + "uxy", "fnk", "ptw", "uwz", "fls", "psy", "fvs", "pxy", "ftw", "pwz", "fxy", "yrx", "ufk", + "xFw", "ymz", "onA", "uds", "xEy", "olk", "ucw", "dBA", "oks", "uci", "dAk", "okg", "dAc", + "ovk", "uhw", "xaz", "dnA", "ots", "ugy", "dlk", "osw", "ugj", "dks", "osi", "dvk", "oxw", + "uiz", "dts", "owy", "dsw", "owj", "dxw", "oyz", "dwy", "dwj", "ofA", "uFs", "xCy", "odk", + "uEw", "xCj", "clA", "ocs", "uEi", "ckk", "ocg", "ckc", "ckE", "cvA", "ohs", "uay", "ctk", + "ogw", "uaj", "css", "ogi", "csg", "csa", "cxs", "oiy", "cww", "oij", "cwi", "cyy", "oFk", + "uCw", "xBj", "cdA", "oEs", "uCi", "cck", "oEg", "uCb", "ccc", "oEa", "ccE", "oED", "chk", + "oaw", "uDj", "cgs", "oai", "cgg", "oab", "cga", "cgD", "obj", "cib", "cFA", "oCs", "uBi", + "cEk", "oCg", "uBb", "cEc", "oCa", "cEE", "oCD", "cEC", "cas", "cag", "caa", "cCk", "uAr", + "oBa", "oBD", "cCB", "tfk", "wpw", "yez", "mnA", "tds", "woy", "mlk", "tcw", "woj", "FBA", + "mks", "FAk", "mvk", "thw", "wqz", "FnA", "mts", "tgy", "Flk", "msw", "Fks", "Fkg", "Fvk", + "mxw", "tiz", "Fts", "mwy", "Fsw", "Fsi", "Fxw", "myz", "Fwy", "Fyz", "vfA", "xps", "yuy", + "vdk", "xow", "yuj", "qlA", "vcs", "xoi", "qkk", "vcg", "xob", "qkc", "vca", "mfA", "tFs", + "wmy", "qvA", "mdk", "tEw", "wmj", "qtk", "vgw", "xqj", "hlA", "Ekk", "mcg", "tEb", "hkk", + "qsg", "hkc", "EvA", "mhs", "tay", "hvA", "Etk", "mgw", "taj", "htk", "qww", "vij", "hss", + "Esg", "hsg", "Exs", "miy", "hxs", "Eww", "mij", "hww", "qyj", "hwi", "Eyy", "hyy", "Eyj", + "hyj", "vFk", "xmw", "ytj", "qdA", "vEs", "xmi", "qck", "vEg", "xmb", "qcc", "vEa", "qcE", + "qcC", "mFk", "tCw", "wlj", "qhk", "mEs", "tCi", "gtA", "Eck", "vai", "tCb", "gsk", "Ecc", + "mEa", "gsc", "qga", "mED", "EcC", "Ehk", "maw", "tDj", "gxk", "Egs", "mai", "gws", "qii", + "mab", "gwg", "Ega", "EgD", "Eiw", "mbj", "gyw", "Eii", "gyi", "Eib", "gyb", "gzj", "qFA", + "vCs", "xli", "qEk", "vCg", "xlb", "qEc", "vCa", "qEE", "vCD", "qEC", "qEB", "EFA", "mCs", + "tBi", "ghA", "EEk", "mCg", "tBb", "ggk", "qag", "vDb", "ggc", "EEE", "mCD", "ggE", "qaD", + "ggC", "Eas", "mDi", "gis", "Eag", "mDb", "gig", "qbb", "gia", "EaD", "giD", "gji", "gjb", + "qCk", "vBg", "xkr", "qCc", "vBa", "qCE", "vBD", "qCC", "qCB", "ECk", "mBg", "tAr", "gak", + "ECc", "mBa", "gac", "qDa", "mBD", "gaE", "ECC", "gaC", "ECB", "EDg", "gbg", "gba", "gbD", + "vAq", "vAn", "qBB", "mAq", "EBE", "gDE", "gDC", "gDB", "lfA", "sps", "wey", "ldk", "sow", + "ClA", "lcs", "soi", "Ckk", "lcg", "Ckc", "CkE", "CvA", "lhs", "sqy", "Ctk", "lgw", "sqj", + "Css", "lgi", "Csg", "Csa", "Cxs", "liy", "Cww", "lij", "Cwi", "Cyy", "Cyj", "tpk", "wuw", + "yhj", "ndA", "tos", "wui", "nck", "tog", "wub", "ncc", "toa", "ncE", "toD", "lFk", "smw", + "wdj", "nhk", "lEs", "smi", "atA", "Cck", "tqi", "smb", "ask", "ngg", "lEa", "asc", "CcE", + "asE", "Chk", "law", "snj", "axk", "Cgs", "trj", "aws", "nii", "lab", "awg", "Cga", "awa", + "Ciw", "lbj", "ayw", "Cii", "ayi", "Cib", "Cjj", "azj", "vpA", "xus", "yxi", "vok", "xug", + "yxb", "voc", "xua", "voE", "xuD", "voC", "nFA", "tms", "wti", "rhA", "nEk", "xvi", "wtb", + "rgk", "vqg", "xvb", "rgc", "nEE", "tmD", "rgE", "vqD", "nEB", "CFA", "lCs", "sli", "ahA", + "CEk", "lCg", "slb", "ixA", "agk", "nag", "tnb", "iwk", "rig", "vrb", "lCD", "iwc", "agE", + "naD", "iwE", "CEB", "Cas", "lDi", "ais", "Cag", "lDb", "iys", "aig", "nbb", "iyg", "rjb", + "CaD", "aiD", "Cbi", "aji", "Cbb", "izi", "ajb", "vmk", "xtg", "ywr", "vmc", "xta", "vmE", + "xtD", "vmC", "vmB", "nCk", "tlg", "wsr", "rak", "nCc", "xtr", "rac", "vna", "tlD", "raE", + "nCC", "raC", "nCB", "raB", "CCk", "lBg", "skr", "aak", "CCc", "lBa", "iik", "aac", "nDa", + "lBD", "iic", "rba", "CCC", "iiE", "aaC", "CCB", "aaB", "CDg", "lBr", "abg", "CDa", "ijg", + "aba", "CDD", "ija", "abD", "CDr", "ijr", "vlc", "xsq", "vlE", "xsn", "vlC", "vlB", "nBc", + "tkq", "rDc", "nBE", "tkn", "rDE", "vln", "rDC", "nBB", "rDB", "CBc", "lAq", "aDc", "CBE", + "lAn", "ibc", "aDE", "nBn", "ibE", "rDn", "CBB", "ibC", "aDB", "ibB", "aDq", "ibq", "ibn", + "xsf", "vkl", "tkf", "nAm", "nAl", "CAo", "aBo", "iDo", "CAl", "aBl", "kpk", "BdA", "kos", + "Bck", "kog", "seb", "Bcc", "koa", "BcE", "koD", "Bhk", "kqw", "sfj", "Bgs", "kqi", "Bgg", + "kqb", "Bga", "BgD", "Biw", "krj", "Bii", "Bib", "Bjj", "lpA", "sus", "whi", "lok", "sug", + "loc", "sua", "loE", "suD", "loC", "BFA", "kms", "sdi", "DhA", "BEk", "svi", "sdb", "Dgk", + "lqg", "svb", "Dgc", "BEE", "kmD", "DgE", "lqD", "BEB", "Bas", "kni", "Dis", "Bag", "knb", + "Dig", "lrb", "Dia", "BaD", "Bbi", "Dji", "Bbb", "Djb", "tuk", "wxg", "yir", "tuc", "wxa", + "tuE", "wxD", "tuC", "tuB", "lmk", "stg", "nqk", "lmc", "sta", "nqc", "tva", "stD", "nqE", + "lmC", "nqC", "lmB", "nqB", "BCk", "klg", "Dak", "BCc", "str", "bik", "Dac", "lna", "klD", + "bic", "nra", "BCC", "biE", "DaC", "BCB", "DaB", "BDg", "klr", "Dbg", "BDa", "bjg", "Dba", + "BDD", "bja", "DbD", "BDr", "Dbr", "bjr", "xxc", "yyq", "xxE", "yyn", "xxC", "xxB", "ttc", + "wwq", "vvc", "xxq", "wwn", "vvE", "xxn", "vvC", "ttB", "vvB", "llc", "ssq", "nnc", "llE", + "ssn", "rrc", "nnE", "ttn", "rrE", "vvn", "llB", "rrC", "nnB", "rrB", "BBc", "kkq", "DDc", + "BBE", "kkn", "bbc", "DDE", "lln", "jjc", "bbE", "nnn", "BBB", "jjE", "rrn", "DDB", "jjC", + "BBq", "DDq", "BBn", "bbq", "DDn", "jjq", "bbn", "jjn", "xwo", "yyf", "xwm", "xwl", "tso", + "wwf", "vto", "xwv", "vtm", "tsl", "vtl", "lko", "ssf", "nlo", "lkm", "rno", "nlm", "lkl", + "rnm", "nll", "rnl", "BAo", "kkf", "DBo", "lkv", "bDo", "DBm", "BAl", "jbo", "bDm", "DBl", + "jbm", "bDl", "jbl", "DBv", "jbv", "xwd", "vsu", "vst", "nku", "rlu", "rlt", "DAu", "bBu", + "jDu", "jDt", "ApA", "Aok", "keg", "Aoc", "AoE", "AoC", "Aqs", "Aqg", "Aqa", "AqD", "Ari", + "Arb", "kuk", "kuc", "sha", "kuE", "shD", "kuC", "kuB", "Amk", "kdg", "Bqk", "kvg", "kda", + "Bqc", "kva", "BqE", "kvD", "BqC", "AmB", "BqB", "Ang", "kdr", "Brg", "kvr", "Bra", "AnD", + "BrD", "Anr", "Brr", "sxc", "sxE", "sxC", "sxB", "ktc", "lvc", "sxq", "sgn", "lvE", "sxn", + "lvC", "ktB", "lvB", "Alc", "Bnc", "AlE", "kcn", "Drc", "BnE", "AlC", "DrE", "BnC", "AlB", + "DrC", "BnB", "Alq", "Bnq", "Aln", "Drq", "Bnn", "Drn", "wyo", "wym", "wyl", "swo", "txo", + "wyv", "txm", "swl", "txl", "kso", "sgf", "lto", "swv", "nvo", "ltm", "ksl", "nvm", "ltl", + "nvl", "Ako", "kcf", "Blo", "ksv", "Dno", "Blm", "Akl", "bro", "Dnm", "Bll", "brm", "Dnl", + "Akv", "Blv", "Dnv", "brv", "yze", "yzd", "wye", "xyu", "wyd", "xyt", "swe", "twu", "swd", + "vxu", "twt", "vxt", "kse", "lsu", "ksd", "ntu", "lst", "rvu", "ypk", "zew", "xdA", "yos", + "zei", "xck", "yog", "zeb", "xcc", "yoa", "xcE", "yoD", "xcC", "xhk", "yqw", "zfj", "utA", + "xgs", "yqi", "usk", "xgg", "yqb", "usc", "xga", "usE", "xgD", "usC", "uxk", "xiw", "yrj", + "ptA", "uws", "xii", "psk", "uwg", "xib", "psc", "uwa", "psE", "uwD", "psC", "pxk", "uyw", + "xjj", "ftA", "pws", "uyi", "fsk", "pwg", "uyb", "fsc", "pwa", "fsE", "pwD", "fxk", "pyw", + "uzj", "fws", "pyi", "fwg", "pyb", "fwa", "fyw", "pzj", "fyi", "fyb", "xFA", "yms", "zdi", + "xEk", "ymg", "zdb", "xEc", "yma", "xEE", "ymD", "xEC", "xEB", "uhA", "xas", "yni", "ugk", + "xag", "ynb", "ugc", "xaa", "ugE", "xaD", "ugC", "ugB", "oxA", "uis", "xbi", "owk", "uig", + "xbb", "owc", "uia", "owE", "uiD", "owC", "owB", "dxA", "oys", "uji", "dwk", "oyg", "ujb", + "dwc", "oya", "dwE", "oyD", "dwC", "dys", "ozi", "dyg", "ozb", "dya", "dyD", "dzi", "dzb", + "xCk", "ylg", "zcr", "xCc", "yla", "xCE", "ylD", "xCC", "xCB", "uak", "xDg", "ylr", "uac", + "xDa", "uaE", "xDD", "uaC", "uaB", "oik", "ubg", "xDr", "oic", "uba", "oiE", "ubD", "oiC", + "oiB", "cyk", "ojg", "ubr", "cyc", "oja", "cyE", "ojD", "cyC", "cyB", "czg", "ojr", "cza", + "czD", "czr", "xBc", "ykq", "xBE", "ykn", "xBC", "xBB", "uDc", "xBq", "uDE", "xBn", "uDC", + "uDB", "obc", "uDq", "obE", "uDn", "obC", "obB", "cjc", "obq", "cjE", "obn", "cjC", "cjB", + "cjq", "cjn", "xAo", "ykf", "xAm", "xAl", "uBo", "xAv", "uBm", "uBl", "oDo", "uBv", "oDm", + "oDl", "cbo", "oDv", "cbm", "cbl", "xAe", "xAd", "uAu", "uAt", "oBu", "oBt", "wpA", "yes", + "zFi", "wok", "yeg", "zFb", "woc", "yea", "woE", "yeD", "woC", "woB", "thA", "wqs", "yfi", + "tgk", "wqg", "yfb", "tgc", "wqa", "tgE", "wqD", "tgC", "tgB", "mxA", "tis", "wri", "mwk", + "tig", "wrb", "mwc", "tia", "mwE", "tiD", "mwC", "mwB", "FxA", "mys", "tji", "Fwk", "myg", + "tjb", "Fwc", "mya", "FwE", "myD", "FwC", "Fys", "mzi", "Fyg", "mzb", "Fya", "FyD", "Fzi", + "Fzb", "yuk", "zhg", "hjs", "yuc", "zha", "hbw", "yuE", "zhD", "hDy", "yuC", "yuB", "wmk", + "ydg", "zEr", "xqk", "wmc", "zhr", "xqc", "yva", "ydD", "xqE", "wmC", "xqC", "wmB", "xqB", + "tak", "wng", "ydr", "vik", "tac", "wna", "vic", "xra", "wnD", "viE", "taC", "viC", "taB", + "viB", "mik", "tbg", "wnr", "qyk", "mic", "tba", "qyc", "vja", "tbD", "qyE", "miC", "qyC", + "miB", "qyB", "Eyk", "mjg", "tbr", "hyk", "Eyc", "mja", "hyc", "qza", "mjD", "hyE", "EyC", + "hyC", "EyB", "Ezg", "mjr", "hzg", "Eza", "hza", "EzD", "hzD", "Ezr", "ytc", "zgq", "grw", + "ytE", "zgn", "gny", "ytC", "glz", "ytB", "wlc", "ycq", "xnc", "wlE", "ycn", "xnE", "ytn", + "xnC", "wlB", "xnB", "tDc", "wlq", "vbc", "tDE", "wln", "vbE", "xnn", "vbC", "tDB", "vbB", + "mbc", "tDq", "qjc", "mbE", "tDn", "qjE", "vbn", "qjC", "mbB", "qjB", "Ejc", "mbq", "gzc", + "EjE", "mbn", "gzE", "qjn", "gzC", "EjB", "gzB", "Ejq", "gzq", "Ejn", "gzn", "yso", "zgf", + "gfy", "ysm", "gdz", "ysl", "wko", "ycf", "xlo", "ysv", "xlm", "wkl", "xll", "tBo", "wkv", + "vDo", "tBm", "vDm", "tBl", "vDl", "mDo", "tBv", "qbo", "vDv", "qbm", "mDl", "qbl", "Ebo", + "mDv", "gjo", "Ebm", "gjm", "Ebl", "gjl", "Ebv", "gjv", "yse", "gFz", "ysd", "wke", "xku", + "wkd", "xkt", "tAu", "vBu", "tAt", "vBt", "mBu", "qDu", "mBt", "qDt", "EDu", "gbu", "EDt", + "gbt", "ysF", "wkF", "xkh", "tAh", "vAx", "mAx", "qBx", "wek", "yFg", "zCr", "wec", "yFa", + "weE", "yFD", "weC", "weB", "sqk", "wfg", "yFr", "sqc", "wfa", "sqE", "wfD", "sqC", "sqB", + "lik", "srg", "wfr", "lic", "sra", "liE", "srD", "liC", "liB", "Cyk", "ljg", "srr", "Cyc", + "lja", "CyE", "ljD", "CyC", "CyB", "Czg", "ljr", "Cza", "CzD", "Czr", "yhc", "zaq", "arw", + "yhE", "zan", "any", "yhC", "alz", "yhB", "wdc", "yEq", "wvc", "wdE", "yEn", "wvE", "yhn", + "wvC", "wdB", "wvB", "snc", "wdq", "trc", "snE", "wdn", "trE", "wvn", "trC", "snB", "trB", + "lbc", "snq", "njc", "lbE", "snn", "njE", "trn", "njC", "lbB", "njB", "Cjc", "lbq", "azc", + "CjE", "lbn", "azE", "njn", "azC", "CjB", "azB", "Cjq", "azq", "Cjn", "azn", "zio", "irs", + "rfy", "zim", "inw", "rdz", "zil", "ily", "ikz", "ygo", "zaf", "afy", "yxo", "ziv", "ivy", + "adz", "yxm", "ygl", "itz", "yxl", "wco", "yEf", "wto", "wcm", "xvo", "yxv", "wcl", "xvm", + "wtl", "xvl", "slo", "wcv", "tno", "slm", "vro", "tnm", "sll", "vrm", "tnl", "vrl", "lDo", + "slv", "nbo", "lDm", "rjo", "nbm", "lDl", "rjm", "nbl", "rjl", "Cbo", "lDv", "ajo", "Cbm", + "izo", "ajm", "Cbl", "izm", "ajl", "izl", "Cbv", "ajv", "zie", "ifw", "rFz", "zid", "idy", + "icz", "yge", "aFz", "ywu", "ygd", "ihz", "ywt", "wce", "wsu", "wcd", "xtu", "wst", "xtt", + "sku", "tlu", "skt", "vnu", "tlt", "vnt", "lBu", "nDu", "lBt", "rbu", "nDt", "rbt", "CDu", + "abu", "CDt", "iju", "abt", "ijt", "ziF", "iFy", "iEz", "ygF", "ywh", "wcF", "wsh", "xsx", + "skh", "tkx", "vlx", "lAx", "nBx", "rDx", "CBx", "aDx", "ibx", "iCz", "wFc", "yCq", "wFE", + "yCn", "wFC", "wFB", "sfc", "wFq", "sfE", "wFn", "sfC", "sfB", "krc", "sfq", "krE", "sfn", + "krC", "krB", "Bjc", "krq", "BjE", "krn", "BjC", "BjB", "Bjq", "Bjn", "yao", "zDf", "Dfy", + "yam", "Ddz", "yal", "wEo", "yCf", "who", "wEm", "whm", "wEl", "whl", "sdo", "wEv", "svo", + "sdm", "svm", "sdl", "svl", "kno", "sdv", "lro", "knm", "lrm", "knl", "lrl", "Bbo", "knv", + "Djo", "Bbm", "Djm", "Bbl", "Djl", "Bbv", "Djv", "zbe", "bfw", "npz", "zbd", "bdy", "bcz", + "yae", "DFz", "yiu", "yad", "bhz", "yit", "wEe", "wgu", "wEd", "wxu", "wgt", "wxt", "scu", + "stu", "sct", "tvu", "stt", "tvt", "klu", "lnu", "klt", "nru", "lnt", "nrt", "BDu", "Dbu", + "BDt", "bju", "Dbt", "bjt", "jfs", "rpy", "jdw", "roz", "jcy", "jcj", "zbF", "bFy", "zjh", + "jhy", "bEz", "jgz", "yaF", "yih", "yyx", "wEF", "wgh", "wwx", "xxx", "sch", "ssx", "ttx", + "vvx", "kkx", "llx", "nnx", "rrx", "BBx", "DDx", "bbx", "jFw", "rmz", "jEy", "jEj", "bCz", + "jaz", "jCy", "jCj", "jBj", "wCo", "wCm", "wCl", "sFo", "wCv", "sFm", "sFl", "kfo", "sFv", + "kfm", "kfl", "Aro", "kfv", "Arm", "Arl", "Arv", "yDe", "Bpz", "yDd", "wCe", "wau", "wCd", + "wat", "sEu", "shu", "sEt", "sht", "kdu", "kvu", "kdt", "kvt", "Anu", "Bru", "Ant", "Brt", + "zDp", "Dpy", "Doz", "yDF", "ybh", "wCF", "wah", "wix", "sEh", "sgx", "sxx", "kcx", "ktx", + "lvx", "Alx", "Bnx", "Drx", "bpw", "nuz", "boy", "boj", "Dmz", "bqz", "jps", "ruy", "jow", + "ruj", "joi", "job", "bmy", "jqy", "bmj", "jqj", "jmw", "rtj", "jmi", "jmb", "blj", "jnj", + "jli", "jlb", "jkr", "sCu", "sCt", "kFu", "kFt", "Afu", "Aft", "wDh", "sCh", "sax", "kEx", + "khx", "Adx", "Avx", "Buz", "Duy", "Duj", "buw", "nxj", "bui", "bub", "Dtj", "bvj", "jus", + "rxi", "jug", "rxb", "jua", "juD", "bti", "jvi", "btb", "jvb", "jtg", "rwr", "jta", "jtD", + "bsr", "jtr", "jsq", "jsn", "Bxj", "Dxi", "Dxb", "bxg", "nyr", "bxa", "bxD", "Dwr", "bxr", + "bwq", "bwn", "pjk", "urw", "ejA", "pbs", "uny", "ebk", "pDw", "ulz", "eDs", "pBy", "eBw", + "zfc", "fjk", "prw", "zfE", "fbs", "pny", "zfC", "fDw", "plz", "zfB", "fBy", "yrc", "zfq", + "frw", "yrE", "zfn", "fny", "yrC", "flz", "yrB", "xjc", "yrq", "xjE", "yrn", "xjC", "xjB", + "uzc", "xjq", "uzE", "xjn", "uzC", "uzB", "pzc", "uzq", "pzE", "uzn", "pzC", "djA", "ors", + "ufy", "dbk", "onw", "udz", "dDs", "oly", "dBw", "okz", "dAy", "zdo", "drs", "ovy", "zdm", + "dnw", "otz", "zdl", "dly", "dkz", "yno", "zdv", "dvy", "ynm", "dtz", "ynl", "xbo", "ynv", + "xbm", "xbl", "ujo", "xbv", "ujm", "ujl", "ozo", "ujv", "ozm", "ozl", "crk", "ofw", "uFz", + "cns", "ody", "clw", "ocz", "cky", "ckj", "zcu", "cvw", "ohz", "zct", "cty", "csz", "ylu", + "cxz", "ylt", "xDu", "xDt", "ubu", "ubt", "oju", "ojt", "cfs", "oFy", "cdw", "oEz", "ccy", + "ccj", "zch", "chy", "cgz", "ykx", "xBx", "uDx", "cFw", "oCz", "cEy", "cEj", "caz", "cCy", + "cCj", "FjA", "mrs", "tfy", "Fbk", "mnw", "tdz", "FDs", "mly", "FBw", "mkz", "FAy", "zFo", + "Frs", "mvy", "zFm", "Fnw", "mtz", "zFl", "Fly", "Fkz", "yfo", "zFv", "Fvy", "yfm", "Ftz", + "yfl", "wro", "yfv", "wrm", "wrl", "tjo", "wrv", "tjm", "tjl", "mzo", "tjv", "mzm", "mzl", + "qrk", "vfw", "xpz", "hbA", "qns", "vdy", "hDk", "qlw", "vcz", "hBs", "qky", "hAw", "qkj", + "hAi", "Erk", "mfw", "tFz", "hrk", "Ens", "mdy", "hns", "qty", "mcz", "hlw", "Eky", "hky", + "Ekj", "hkj", "zEu", "Evw", "mhz", "zhu", "zEt", "hvw", "Ety", "zht", "hty", "Esz", "hsz", + "ydu", "Exz", "yvu", "ydt", "hxz", "yvt", "wnu", "xru", "wnt", "xrt", "tbu", "vju", "tbt", + "vjt", "mju", "mjt", "grA", "qfs", "vFy", "gnk", "qdw", "vEz", "gls", "qcy", "gkw", "qcj", + "gki", "gkb", "Efs", "mFy", "gvs", "Edw", "mEz", "gtw", "qgz", "gsy", "Ecj", "gsj", "zEh", + "Ehy", "zgx", "gxy", "Egz", "gwz", "ycx", "ytx", "wlx", "xnx", "tDx", "vbx", "mbx", "gfk", + "qFw", "vCz", "gds", "qEy", "gcw", "qEj", "gci", "gcb", "EFw", "mCz", "ghw", "EEy", "ggy", + "EEj", "ggj", "Eaz", "giz", "gFs", "qCy", "gEw", "qCj", "gEi", "gEb", "ECy", "gay", "ECj", + "gaj", "gCw", "qBj", "gCi", "gCb", "EBj", "gDj", "gBi", "gBb", "Crk", "lfw", "spz", "Cns", + "ldy", "Clw", "lcz", "Cky", "Ckj", "zCu", "Cvw", "lhz", "zCt", "Cty", "Csz", "yFu", "Cxz", + "yFt", "wfu", "wft", "sru", "srt", "lju", "ljt", "arA", "nfs", "tpy", "ank", "ndw", "toz", + "als", "ncy", "akw", "ncj", "aki", "akb", "Cfs", "lFy", "avs", "Cdw", "lEz", "atw", "ngz", + "asy", "Ccj", "asj", "zCh", "Chy", "zax", "axy", "Cgz", "awz", "yEx", "yhx", "wdx", "wvx", + "snx", "trx", "lbx", "rfk", "vpw", "xuz", "inA", "rds", "voy", "ilk", "rcw", "voj", "iks", + "rci", "ikg", "rcb", "ika", "afk", "nFw", "tmz", "ivk", "ads", "nEy", "its", "rgy", "nEj", + "isw", "aci", "isi", "acb", "isb", "CFw", "lCz", "ahw", "CEy", "ixw", "agy", "CEj", "iwy", + "agj", "iwj", "Caz", "aiz", "iyz", "ifA", "rFs", "vmy", "idk", "rEw", "vmj", "ics", "rEi", + "icg", "rEb", "ica", "icD", "aFs", "nCy", "ihs", "aEw", "nCj", "igw", "raj", "igi", "aEb", + "igb", "CCy", "aay", "CCj", "iiy", "aaj", "iij", "iFk", "rCw", "vlj", "iEs", "rCi", "iEg", + "rCb", "iEa", "iED", "aCw", "nBj", "iaw", "aCi", "iai", "aCb", "iab", "CBj", "aDj", "ibj", + "iCs", "rBi", "iCg", "rBb", "iCa", "iCD", "aBi", "iDi", "aBb", "iDb", "iBg", "rAr", "iBa", + "iBD", "aAr", "iBr", "iAq", "iAn", "Bfs", "kpy", "Bdw", "koz", "Bcy", "Bcj", "Bhy", "Bgz", + "yCx", "wFx", "sfx", "krx", "Dfk", "lpw", "suz", "Dds", "loy", "Dcw", "loj", "Dci", "Dcb", + "BFw", "kmz", "Dhw", "BEy", "Dgy", "BEj", "Dgj", "Baz", "Diz", "bfA", "nps", "tuy", "bdk", + "now", "tuj", "bcs", "noi", "bcg", "nob", "bca", "bcD", "DFs", "lmy", "bhs", "DEw", "lmj", + "bgw", "DEi", "bgi", "DEb", "bgb", "BCy", "Day", "BCj", "biy", "Daj", "bij", "rpk", "vuw", + "xxj", "jdA", "ros", "vui", "jck", "rog", "vub", "jcc", "roa", "jcE", "roD", "jcC", "bFk", + "nmw", "ttj", "jhk", "bEs", "nmi", "jgs", "rqi", "nmb", "jgg", "bEa", "jga", "bED", "jgD", + "DCw", "llj", "baw", "DCi", "jiw", "bai", "DCb", "jii", "bab", "jib", "BBj", "DDj", "bbj", + "jjj", "jFA", "rms", "vti", "jEk", "rmg", "vtb", "jEc", "rma", "jEE", "rmD", "jEC", "jEB", + "bCs", "nli", "jas", "bCg", "nlb", "jag", "rnb", "jaa", "bCD", "jaD", "DBi", "bDi", "DBb", + "jbi", "bDb", "jbb", "jCk", "rlg", "vsr", "jCc", "rla", "jCE", "rlD", "jCC", "jCB", "bBg", + "nkr", "jDg", "bBa", "jDa", "bBD", "jDD", "DAr", "bBr", "jDr", "jBc", "rkq", "jBE", "rkn", + "jBC", "jBB", "bAq", "jBq", "bAn", "jBn", "jAo", "rkf", "jAm", "jAl", "bAf", "jAv", "Apw", + "kez", "Aoy", "Aoj", "Aqz", "Bps", "kuy", "Bow", "kuj", "Boi", "Bob", "Amy", "Bqy", "Amj", + "Bqj", "Dpk", "luw", "sxj", "Dos", "lui", "Dog", "lub", "Doa", "DoD", "Bmw", "ktj", "Dqw", + "Bmi", "Dqi", "Bmb", "Dqb", "Alj", "Bnj", "Drj", "bpA", "nus", "txi", "bok", "nug", "txb", + "boc", "nua", "boE", "nuD", "boC", "boB", "Dms", "lti", "bqs", "Dmg", "ltb", "bqg", "nvb", + "bqa", "DmD", "bqD", "Bli", "Dni", "Blb", "bri", "Dnb", "brb", "ruk", "vxg", "xyr", "ruc", + "vxa", "ruE", "vxD", "ruC", "ruB", "bmk", "ntg", "twr", "jqk", "bmc", "nta", "jqc", "rva", + "ntD", "jqE", "bmC", "jqC", "bmB", "jqB", "Dlg", "lsr", "bng", "Dla", "jrg", "bna", "DlD", + "jra", "bnD", "jrD", "Bkr", "Dlr", "bnr", "jrr", "rtc", "vwq", "rtE", "vwn", "rtC", "rtB", + "blc", "nsq", "jnc", "blE", "nsn", "jnE", "rtn", "jnC", "blB", "jnB", "Dkq", "blq", "Dkn", + "jnq", "bln", "jnn", "rso", "vwf", "rsm", "rsl", "bko", "nsf", "jlo", "bkm", "jlm", "bkl", + "jll", "Dkf", "bkv", "jlv", "rse", "rsd", "bke", "jku", "bkd", "jkt", "Aey", "Aej", "Auw", + "khj", "Aui", "Aub", "Adj", "Avj", "Bus", "kxi", "Bug", "kxb", "Bua", "BuD", "Ati", "Bvi", + "Atb", "Bvb", "Duk", "lxg", "syr", "Duc", "lxa", "DuE", "lxD", "DuC", "DuB", "Btg", "kwr", + "Dvg", "lxr", "Dva", "BtD", "DvD", "Asr", "Btr", "Dvr", "nxc", "tyq", "nxE", "tyn", "nxC", + "nxB", "Dtc", "lwq", "bvc", "nxq", "lwn", "bvE", "DtC", "bvC", "DtB", "bvB", "Bsq", "Dtq", + "Bsn", "bvq", "Dtn", "bvn", "vyo", "xzf", "vym", "vyl", "nwo", "tyf", "rxo", "nwm", "rxm", + "nwl", "rxl", "Dso", "lwf", "bto", "Dsm", "jvo", "btm", "Dsl", "jvm", "btl", "jvl", "Bsf", + "Dsv", "btv", "jvv", "vye", "vyd", "nwe", "rwu", "nwd", "rwt", "Dse", "bsu", "Dsd", "jtu", + "bst", "jtt", "vyF", "nwF", "rwh", "DsF", "bsh", "jsx", "Ahi", "Ahb", "Axg", "kir", "Axa", + "AxD", "Agr", "Axr", "Bxc", "kyq", "BxE", "kyn", "BxC", "BxB", "Awq", "Bxq", "Awn", "Bxn", + "lyo", "szf", "lym", "lyl", "Bwo", "kyf", "Dxo", "lyv", "Dxm", "Bwl", "Dxl", "Awf", "Bwv", + "Dxv", "tze", "tzd", "lye", "nyu", "lyd", "nyt", "Bwe", "Dwu", "Bwd", "bxu", "Dwt", "bxt", + "tzF", "lyF", "nyh", "BwF", "Dwh", "bwx", "Aiq", "Ain", "Ayo", "kjf", "Aym", "Ayl", "Aif", + "Ayv", "kze", "kzd", "Aye", "Byu", "Ayd", "Byt", "szp" }; + +/* converts values into bar patterns - replacing Grand Zebu's true type font */ +static char *PDFttf[35] = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", + "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", + "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", + "11011", "11100", "11101", "11110", "11111", "01", "1111111101010100", "11111101000101001"}; + +/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */ +static int Microcoeffs[344] = { + /* k = 7 */ + 76, 925, 537, 597, 784, 691, 437, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379, + + /* k = 9 */ + 567, 527, 622, 257, 289, 362, 501, 441, 205, + + /* k = 10 */ + 377, 457, 64, 244, 826, 841, 818, 691, 266, 612, + + /* k = 11 */ + 462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904, + + /* k = 12 */ + 597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851, + + /* k = 13 */ + 764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692, + + /* k = 14 */ + 669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215, + + /* k = 15 */ + 460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642, + + /* k = 16 */ + 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, + + /* k = 18 */ + 279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756, + 760, 573, + + /* k = 21 */ + 108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691, + 347, 165, 193, 259, 568, + + /* k = 26 */ + 443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893, + 699, 245, 441, 454, 325, 858, 131, 847, 764, 169, + + /* k = 32 */ + 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, + 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, + + /* k = 38 */ + 234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684, + 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771, + 554, 289, 231, 125, 117, 518, + + /* k = 44 */ + 476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405, + 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213, + 31, 560, 231, 758, 103, 271, 572, 436, 339, 730, 82, 285, + + /* k = 50 */ + 923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303, + 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26, + 579, 623, 766, 146, 10, 739, 246, 127, 71, 244, 211, 477, 920, 876, 427, 820, + 718, 435 }; + +/* rows, columns, error codewords, k-offset of valid MicroPDF417 sizes from ISO/IEC 24728:2006 */ +static int MicroVariants[170] = +{ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, + 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 }; +/* rows, columns, error codewords, k-offset */ + +/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables 10, 11 and 12 */ +static int RAPTable[136] = +{ 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, + 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, + 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 }; + +/* Left and Right Row Address Pattern from Table 2 */ +static char *RAPLR[53] = {"", "221311", "311311", "312211", "222211", "213211", "214111", "223111", + "313111", "322111", "412111", "421111", "331111", "241111", "232111", "231211", "321211", + "411211", "411121", "411112", "321112", "312112", "311212", "311221", "311131", "311122", + "311113", "221113", "221122", "221131", "221221", "222121", "312121", "321121", "231121", + "231112", "222112", "213112", "212212", "212221", "212131", "212122", "212113", "211213", + "211123", "211132", "211141", "211231", "211222", "211312", "211321", "211411", "212311" }; + +/* Centre Row Address Pattern from Table 2 */ +static char *RAPC[53] = {"", "112231", "121231", "122131", "131131", "131221", "132121", "141121", + "141211", "142111", "133111", "132211", "131311", "122311", "123211", "124111", "115111", + "114211", "114121", "123121", "123112", "122212", "122221", "121321", "121411", "112411", + "113311", "113221", "113212", "113122", "122122", "131122", "131113", "122113", "113113", + "112213", "112222", "112312", "112321", "111421", "111331", "111322", "111232", "111223", + "111133", "111124", "111214", "112114", "121114", "121123", "121132", "112132", "112141" }; + +void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block); \ No newline at end of file diff --git a/backend/plessey.c b/backend/plessey.c new file mode 100644 index 00000000..baaf9700 --- /dev/null +++ b/backend/plessey.c @@ -0,0 +1,496 @@ +/* plessey.c - Handles Plessey and MSI Plessey */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include +#include "common.h" + + +#define SSET "0123456789ABCDEF" +static char *PlessTable[16] = {"13131313", "31131313", "13311313", "31311313", "13133113", "31133113", + "13313113", "31313113", "13131331", "31131331", "13311331", "31311331", "13133131", + "31133131", "13313131", "31313131"}; + +static char *MSITable[10] = {"12121212", "12121221", "12122112", "12122121", "12211212", "12211221", + "12212112", "12212121", "21121212", "21121221"}; + + +int plessey(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Not MSI/Plessey but the older Plessey standard */ + + unsigned int i, check; + unsigned char *checkptr; + static char grid[9] = {1,1,1,1,0,1,0,0,1}; + char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */ + int error_number; + + error_number = 0; + + if(length > 65) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(SSET, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + checkptr = (unsigned char *)calloc (1, length * 4 + 8); + + /* Start character */ + strcpy(dest, "31311331"); + + /* Data area */ + for(i = 0; i < length; i++) + { + check = posn(SSET, source[i]); + lookup(SSET, PlessTable, source[i], dest); + checkptr[4*i] = check & 1; + checkptr[4*i+1] = (check >> 1) & 1; + checkptr[4*i+2] = (check >> 2) & 1; + checkptr[4*i+3] = (check >> 3) & 1; + } + + /* CRC check digit code adapted from code by Leonid A. Broukhis + used in GNU Barcode */ + + for (i = 0; i < (4 * length); i++) { + int j; + if (checkptr[i]) + for (j = 0; j < 9; j++) + checkptr[i+j] ^= grid[j]; + } + + for (i = 0; i < 8; i++) { + switch(checkptr[length * 4 + i]) + { + case 0: concat(dest, "13"); break; + case 1: concat(dest, "31"); break; + } + } + + /* Stop character */ + concat(dest, "331311313"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + free(checkptr); + return error_number; +} + +int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Plain MSI Plessey - does not calculate any check character */ + + unsigned int i; + char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */ + + if(length > 55) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + for(i = 0; i < length; i++) + { + lookup(NEON, MSITable, source[i], dest); + } + + /* Stop character */ + concat (dest, "121"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return 0; +} + +int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island + http://www.barcodeisland.com/ */ + + unsigned long i, wright, dau, pedwar, pump, n; + char un[200], tri[32]; + int error_number, h; + char dest[1000]; + + error_number = 0; + + if(length > 18) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for(i = 0; i < length; i++) + { + lookup(NEON, MSITable, source[i], dest); + } + + /* caluculate check digit */ + wright = 0; + n = ((length % 2) == 0) ? 1 : 0; + for(i = n; i < length; i += 2) + { + un[wright++] = source[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for(i = 0; i < h; i++) + { + pedwar += ctoi(tri[i]); + } + + n = length % 2; + for(i = n; i < length; i+=2) + { + pedwar += ctoi(source[i]); + } + + pump = (10 - pedwar % 10); + if(pump == 10) + { + pump = 0; + } + + /* draw check digit */ + lookup(NEON, MSITable, itoc(pump), dest); + + /* Stop character */ + concat (dest, "121"); + expand(symbol, dest); + + ustrcpy(symbol->text, source); + symbol->text[length] = itoc(pump); + symbol->text[length + 1] = '\0'; + return error_number; +} + +int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) +{ /* MSI Plessey with two Modulo 10 check digits - algorithm from + Barcode Island http://www.barcodeisland.com/ */ + + unsigned long i, n, wright, dau, pedwar, pump, chwech; + char un[16], tri[32]; + int error_number, h; + char dest[1000]; + + error_number = 0; + + if(src_len > 18) { /* No Entry Stack Smashers! limit because of str->number conversion*/ + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for(i = 0; i < src_len; i++) + { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate first check digit */ + wright = 0; + + n = ((src_len %2) == 0) ? 1 : 0; + for(i = n; i < src_len; i += 2) + { + un[wright++] = source[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for(i = 0; i < h; i++) + { + pedwar += ctoi(tri[i]); + } + + n = src_len % 2; + for(i = n; i < src_len; i += 2) + { + pedwar += ctoi(source[i]); + } + + pump = 10 - pedwar % 10; + if(pump == 10) + { + pump = 0; + } + + /* calculate second check digit */ + wright = 0; + n = src_len % 2; + for(i = n; i < src_len; i += 2) + { + un[wright++] = source[i]; + } + un[wright++] = itoc(pump); + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for(i = 0; i < h; i++) + { + pedwar += ctoi(tri[i]); + } + + + i = ((src_len % 2) == 0) ? 1 : 0; + for(; i < src_len; i += 2) + { + pedwar += ctoi(source[i]); + } + + chwech = 10 - pedwar % 10; + if(chwech == 10) + { + chwech = 0; + } + + /* Draw check digits */ + lookup(NEON, MSITable, itoc(pump), dest); + lookup(NEON, MSITable, itoc(chwech), dest); + + /* Stop character */ + concat (dest, "121"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + symbol->text[src_len] = itoc(pump); + symbol->text[src_len + 1] = itoc(chwech); + symbol->text[src_len + 2] = '\0'; + + return error_number; +} + + +int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) +{ + /* Calculate a Modulo 11 check digit using the system discussed on Wikipedia - + see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */ + /* uses the IBM weight system */ + + int i, weight, x, check; + int error_number; + char dest[1000]; + + error_number = 0; + + if(src_len > 55) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for(i = 0; i < src_len; i++) + { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate check digit */ + x = 0; + weight = 2; + for(i = src_len - 1; i >= 0; i--) { + x += weight * ctoi(source[i]); + weight++; + if(weight > 7) { + weight = 2; + } + } + + check = (11 - (x % 11)) % 11; + if(check == 10) { + lookup(NEON, MSITable, '1', dest); + lookup(NEON, MSITable, '0', dest); + } else { + lookup(NEON, MSITable, itoc(check), dest); + } + + /* stop character */ + concat (dest, "121"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + if(check == 10) { + concat((char* )symbol->text, "10"); + } else { + symbol->text[src_len] = itoc(check); + symbol->text[src_len + 1] = '\0'; + } + + return error_number; +} + +int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) +{ + /* Combining the Barcode Island and Wikipedia code */ + /* Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */ + /* Weighted using the IBM system */ + + unsigned long i, weight, x, check, wright, dau, pedwar, pump, h; + char un[16], tri[16]; + int error_number; + char dest[1000]; + unsigned char temp[32]; + unsigned int temp_len; + + error_number = 0; + + if(src_len > 18) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for(i = 0; i < src_len; i++) + { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate first (mod 11) digit */ + x = 0; + weight = 2; + for(i = src_len - 1; i >= 0; i--) { + x += weight * ctoi(source[i]); + weight++; + if(weight > 7) { + weight = 2; + } + } + + check = (11 - (x % 11)) % 11; + ustrcpy(temp, source); + temp_len = src_len; + if(check == 10) { + lookup(NEON, MSITable, '1', dest); + lookup(NEON, MSITable, '0', dest); + uconcat(temp, (unsigned char *)"10"); + temp_len += 2; + } else { + lookup(NEON, MSITable, itoc(check), dest); + temp[temp_len++] = itoc(check); + temp[temp_len] = '\0'; + } + + /* caluculate second (mod 10) check digit */ + wright = 0; + i = ((temp_len % 2) == 0) ? 1 : 0; + for(; i < temp_len; i += 2) + { + un[wright++] = temp[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for(i = 0; i < h; i++) + { + pedwar += ctoi(tri[i]); + } + + i = temp_len % 2; + for(; i < temp_len; i+=2) + { + pedwar += ctoi(temp[i]); + } + + pump = 10 - pedwar % 10; + if(pump == 10) + { + pump = 0; + } + + /* draw check digit */ + lookup(NEON, MSITable, itoc(pump), dest); + + /* stop character */ + concat (dest, "121"); + expand(symbol, dest); + + temp[temp_len++] = itoc(pump); + temp[temp_len] = '\0'; + + + ustrcpy(symbol->text, temp); + return error_number; +} + +int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) { + int error_number; + + error_number = is_sane(NEON, source, length); + if(error_number != 0) { + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + + + if((symbol->option_2 < 0) || (symbol->option_2 > 4)) { + symbol->option_2 = 0; + } + + switch(symbol->option_2) { + case 0: error_number = msi_plessey(symbol, source, length); break; + case 1: error_number = msi_plessey_mod10(symbol, source, length); break; + case 2: error_number = msi_plessey_mod1010(symbol, source, length); break; + case 3: error_number = msi_plessey_mod11(symbol, source, length); break; + case 4: error_number = msi_plessey_mod1110(symbol, source, length); break; + } + + return error_number; +} diff --git a/backend/png.c b/backend/png.c new file mode 100644 index 00000000..f93f17c1 --- /dev/null +++ b/backend/png.c @@ -0,0 +1,1138 @@ +/* png.c - Handles output to PNG file */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#ifdef _MSC_VER +#include +#include +#endif +#include +#include +#include "common.h" + +#ifdef _MSC_VER +#include +#endif /* _MSC_VER */ + +#ifndef NO_PNG +#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ +#include "maxipng.h" /* Maxicode shapes */ +#endif /* NO_PNG */ + +#include "font.h" /* Font for human readable text */ + +#define SSET "0123456789ABCDEF" + +#define PNG_DATA 100 +#define BMP_DATA 200 + +#ifndef NO_PNG +struct mainprog_info_type { + long width; + long height; + FILE *outfile; + jmp_buf jmpbuf; +}; + +static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) +{ + struct mainprog_info_type *graphic; + + fprintf(stderr, "writepng libpng error: %s\n", msg); + fflush(stderr); + + graphic = (struct mainprog_info_type*)png_get_error_ptr(png_ptr); + if (graphic == NULL) { /* we are completely hosed now */ + fprintf(stderr, + "writepng severe error: jmpbuf not recoverable; terminating.\n"); + fflush(stderr); + return; + } + longjmp(graphic->jmpbuf, 1); +} + +int png_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) +{ + struct mainprog_info_type wpng_info; + struct mainprog_info_type *graphic; + +#ifndef _MSC_VER + unsigned char outdata[image_width * 3]; +#else + unsigned char* outdata = (unsigned char*)_alloca(image_width * 3); +#endif + png_structp png_ptr; + png_infop info_ptr; + graphic = &wpng_info; + unsigned long rowbytes; + unsigned char *image_data; + int i, row, column, errno; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + + switch(rotate_angle) { + case 0: + case 180: + graphic->width = image_width; + graphic->height = image_height; + break; + case 90: + case 270: + graphic->width = image_height; + graphic->height = image_width; + break; + } + + /* sort out colour options */ + to_upper((unsigned char*)symbol->fgcolour); + to_upper((unsigned char*)symbol->bgcolour); + + if(strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + if(strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + errno = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); + if (errno == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + errno = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); + if (errno == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + /* Open output file in binary mode */ + if((symbol->output_options & BARCODE_STDOUT) != 0) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "Can't open output file"); + return ERROR_FILE_ACCESS; + } +#endif + graphic->outfile = stdout; + } else { + if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) { + strcpy(symbol->errtxt, "Can't open output file"); + return ERROR_FILE_ACCESS; + } + } + + /* Set up error handling routine as proc() above */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic, writepng_error_handler, NULL); + if (!png_ptr) { + strcpy(symbol->errtxt, "Out of memory"); + return ERROR_MEMORY; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, NULL); + strcpy(symbol->errtxt, "Out of memory"); + return ERROR_MEMORY; + } + + /* catch jumping here */ + if (setjmp(graphic->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + strcpy(symbol->errtxt, "libpng error occurred"); + return ERROR_MEMORY; + } + + /* open output file with libpng */ + png_init_io(png_ptr, graphic->outfile); + + /* set compression */ + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + + /* set Header block */ + png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /* write all chunks up to (but not including) first IDAT */ + png_write_info(png_ptr, info_ptr); + + /* set up the transformations: for now, just pack low-bit-depth pixels + into bytes (one, two or four pixels per byte) */ + png_set_packing(png_ptr); + + /* set rowbytes - depends on picture depth */ + rowbytes = wpng_info.width * 3; + + /* Pixel Plotting */ + + switch(rotate_angle) { + case 0: /* Plot the right way up */ + for(row = 0; row < image_height; row++) { + for(column = 0; column < image_width; column++) { + i = column * 3; + switch(*(pixelbuf + (image_width * row) + column)) + { + case '1': + outdata[i] = fgred; + outdata[i + 1] = fggrn; + outdata[i + 2] = fgblu; + break; + default: + outdata[i] = bgred; + outdata[i + 1] = bggrn; + outdata[i + 2] = bgblu; + break; + + } + } + /* write row contents to file */ + image_data = outdata; + png_write_row(png_ptr, image_data); + } + break; + case 90: /* Plot 90 degrees clockwise */ + for(row = 0; row < image_width; row++) { + for(column = 0; column < image_height; column++) { + i = column * 3; + switch(*(pixelbuf + (image_width * (image_height - column - 1)) + row)) + { + case '1': + outdata[i] = fgred; + outdata[i + 1] = fggrn; + outdata[i + 2] = fgblu; + break; + default: + outdata[i] = bgred; + outdata[i + 1] = bggrn; + outdata[i + 2] = bgblu; + break; + + } + } + + /* write row contents to file */ + image_data = outdata; + png_write_row(png_ptr, image_data); + } + break; + case 180: /* Plot upside down */ + for(row = 0; row < image_height; row++) { + for(column = 0; column < image_width; column++) { + i = column * 3; + switch(*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) + { + case '1': + outdata[i] = fgred; + outdata[i + 1] = fggrn; + outdata[i + 2] = fgblu; + break; + default: + outdata[i] = bgred; + outdata[i + 1] = bggrn; + outdata[i + 2] = bgblu; + break; + + } + } + + /* write row contents to file */ + image_data = outdata; + png_write_row(png_ptr, image_data); + } + break; + case 270: /* Plot 90 degrees anti-clockwise */ + for(row = 0; row < image_width; row++) { + for(column = 0; column < image_height; column++) { + i = column * 3; + switch(*(pixelbuf + (image_width * column) + (image_width - row - 1))) + { + case '1': + outdata[i] = fgred; + outdata[i + 1] = fggrn; + outdata[i + 2] = fgblu; + break; + default: + outdata[i] = bgred; + outdata[i + 1] = bggrn; + outdata[i + 2] = bgblu; + break; + + } + } + + /* write row contents to file */ + image_data = outdata; + png_write_row(png_ptr, image_data); + } + break; + } + + /* End the file */ + png_write_end(png_ptr, NULL); + + /* make sure we have disengaged */ + if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(wpng_info.outfile); + return 0; +} +#endif /* NO_PNG */ + +int bmp_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) +{ + unsigned long rowbytes; + int i, row, column, errno; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + + switch(rotate_angle) { + case 0: + case 180: + symbol->bitmap_width = image_width; + symbol->bitmap_height = image_height; + break; + case 90: + case 270: + symbol->bitmap_width = image_height; + symbol->bitmap_height = image_width; + break; + } + + if (symbol->bitmap != NULL) + free(symbol->bitmap); + + symbol->bitmap = (char *) malloc(image_width * image_height * 3); + + + /* sort out colour options */ + to_upper((unsigned char*)symbol->fgcolour); + to_upper((unsigned char*)symbol->bgcolour); + + if(strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + if(strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + errno = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); + if (errno == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + errno = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->fgcolour)); + if (errno == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + /* set rowbytes - depends on picture depth */ + rowbytes = symbol->bitmap_width * 3; + + /* Pixel Plotting */ + i = 0; + switch(rotate_angle) { + case 0: /* Plot the right way up */ + for(row = 0; row < image_height; row++) { + for(column = 0; column < image_width; column++) { + switch(*(pixelbuf + (image_width * row) + column)) + { + case '1': + symbol->bitmap[i++] = fgred; + symbol->bitmap[i++] = fggrn; + symbol->bitmap[i++] = fgblu; + break; + default: + symbol->bitmap[i++] = bgred; + symbol->bitmap[i++] = bggrn; + symbol->bitmap[i++] = bgblu; + break; + + } + } + } + break; + case 90: /* Plot 90 degrees clockwise */ + for(row = 0; row < image_width; row++) { + for(column = 0; column < image_height; column++) { + switch(*(pixelbuf + (image_width * (image_height - column - 1)) + row)) + { + case '1': + symbol->bitmap[i++] = fgred; + symbol->bitmap[i++] = fggrn; + symbol->bitmap[i++] = fgblu; + break; + default: + symbol->bitmap[i++] = bgred; + symbol->bitmap[i++] = bggrn; + symbol->bitmap[i++] = bgblu; + break; + + } + } + } + break; + case 180: /* Plot upside down */ + for(row = 0; row < image_height; row++) { + for(column = 0; column < image_width; column++) { + switch(*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) + { + case '1': + symbol->bitmap[i++] = fgred; + symbol->bitmap[i++] = fggrn; + symbol->bitmap[i++] = fgblu; + break; + default: + symbol->bitmap[i++] = bgred; + symbol->bitmap[i++] = bggrn; + symbol->bitmap[i++] = bgblu; + break; + + } + } + } + break; + case 270: /* Plot 90 degrees anti-clockwise */ + for(row = 0; row < image_width; row++) { + for(column = 0; column < image_height; column++) { + switch(*(pixelbuf + (image_width * column) + (image_width - row - 1))) + { + case '1': + symbol->bitmap[i++] = fgred; + symbol->bitmap[i++] = fggrn; + symbol->bitmap[i++] = fgblu; + break; + default: + symbol->bitmap[i++] = bgred; + symbol->bitmap[i++] = bggrn; + symbol->bitmap[i++] = bgblu; + break; + + } + } + } + break; + } + + return 0; +} + +int png_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) +{ + int error_number; + float scaler = symbol->scale; + char *scaled_pixelbuf; + int horiz, vert, i; + int scale_width, scale_height; + + if(scaler == 0) { scaler = 0.5; } + scale_width = image_width * scaler; + scale_height = image_height * scaler; + + /* Apply scale options by creating another pixel buffer */ + if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + printf("Insufficient memory for pixel buffer"); + return ERROR_ENCODING_PROBLEM; + } else { + for(i = 0; i < (scale_width * scale_height); i++) { + *(scaled_pixelbuf + i) = '0'; + } + } + + for(vert = 0; vert < scale_height; vert++) { + for(horiz = 0; horiz < scale_width; horiz++) { + *(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int)(vert / scaler) * image_width) + (int)(horiz / scaler)); + } + } + + if(image_type == PNG_DATA) { +#ifndef NO_PNG + error_number = png_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle); +#else + return ERROR_INVALID_OPTION; +#endif + } else { + error_number = bmp_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle); + } + + free(scaled_pixelbuf); + + return error_number; +} + +void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) +{ + /* Draw a rectangle */ + int i, j, png_ypos; + + png_ypos = image_height - ypos - ylen; + /* This fudge is needed because EPS measures height from the bottom up but + PNG measures y position from the top down */ + + for(i = (xpos); i < (xpos + xlen); i++) { + for( j = (png_ypos); j < (png_ypos + ylen); j++) { + *(pixelbuf + (image_width * j) + i) = '1'; + } + } +} + +int bullseye_pixel(int row, int col) { + int block_val, block_pos, return_val; + + block_val = bullseye_compressed[(row * 12) + (col / 8)]; + return_val = 0; + block_pos = col % 8; + + switch(block_pos) { + case 0: if((block_val & 0x80) != 0) { return_val = 1; } break; + case 1: if((block_val & 0x40) != 0) { return_val = 1; } break; + case 2: if((block_val & 0x20) != 0) { return_val = 1; } break; + case 3: if((block_val & 0x10) != 0) { return_val = 1; } break; + case 4: if((block_val & 0x08) != 0) { return_val = 1; } break; + case 5: if((block_val & 0x04) != 0) { return_val = 1; } break; + case 6: if((block_val & 0x02) != 0) { return_val = 1; } break; + case 7: if((block_val & 0x01) != 0) { return_val = 1; } break; + } + + return return_val; +} + +void draw_bullseye(char *pixelbuf, int image_width, int xoffset, int yoffset) +{ + /* Central bullseye in Maxicode symbols */ + int i, j; + + for(j = 103; j < 196; j++) { + for(i = 0; i < 93; i++) { + if(bullseye_pixel(j - 103, i)) { + /* if(bullseye[(((j - 103) * 93) + i)] == 1) { */ + *(pixelbuf + (image_width * j) + (image_width * yoffset) + i + 99 + xoffset) = '1'; + } + } + } +} + +void draw_hexagon(char *pixelbuf, int image_width, int xposn, int yposn) +{ + /* Put a hexagon into the pixel buffer */ + int i, j; + + for(i = 0; i < 12; i++) { + for(j = 0; j < 10; j++) { + if(hexagon[(i * 10) + j] == 1) { + *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = '1'; + } + } + } +} + +void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int image_width, int image_height) +{ + /* Put a letter into a position */ + int skip, i, j, glyph_no, alphabet; + + skip = 0; + alphabet = 0; + + if(letter < 33) { skip = 1; } + if((letter > 127) && (letter < 161)) { skip = 1; } + + if(skip == 0) { + if(letter > 128) { + alphabet = 1; + glyph_no = letter - 161; + } else { + glyph_no = letter - 33; + } + + for(i = 0; i <= 13; i++) { + for(j = 0; j < 7; j++) { + if(alphabet == 0) { + if(ascii_font[(glyph_no * 7) + (i * 665) + j - 1] == 1) { + *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; + } + } else { + if(ascii_ext_font[(glyph_no * 7) + (i * 665) + j - 1] == 1) { + *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; + } + } + } + } + } +} + +void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int image_width, int image_height) +{ + /* Plot a string into the pixel buffer */ + int i, string_length, string_left_hand; + + string_length = strlen(input_string); + string_left_hand = xposn - ((7 * string_length) / 2); + + for(i = 0; i < string_length; i++) { + draw_letter(pixbuf, input_string[i], string_left_hand + (i * 7), yposn, image_width, image_height); + } + +} + +int maxi_png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) +{ + int i, row, column, xposn, yposn; + int image_height, image_width; + char *pixelbuf; + int error_number; + int xoffset, yoffset; + + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + image_width = 300 + (2 * xoffset * 2); + image_height = 300 + (2 * yoffset * 2); + + if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + printf("Insifficient memory for pixel buffer"); + return ERROR_ENCODING_PROBLEM; + } else { + for(i = 0; i < (image_width * image_height); i++) { + *(pixelbuf + i) = '0'; + } + } + + draw_bullseye(pixelbuf, image_width, (2 * xoffset), (2 * yoffset)); + + for(row = 0; row < symbol->rows; row++) { + yposn = row * 9; + for(column = 0; column < symbol->width; column++) { + xposn = column * 10; + if(module_is_set(symbol, row, column)) { + if((row % 2) == 0) { + /* Even (full) row */ + draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); + } else { + /* Odd (reduced) row */ + xposn += 5; + draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); + } + } + } + } + + if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + /* boundary bars */ + draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height); + } + + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height); + draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height); + } + + error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); + free(pixelbuf); + return error_number; +} + +void to_latin1(unsigned char source[], unsigned char preprocessed[]) +{ + int j, i, input_length; + + input_length = ustrlen(source); + + j = 0; + i = 0; + do { + if(source[i] < 128) { + preprocessed[j] = source[i]; + j++; + i++; + } else { + if(source[i] == 0xC2) { + preprocessed[j] = source[i + 1]; + j++; + i += 2; + } + if(source[i] == 0xC3) { + preprocessed[j] = source[i + 1] + 64; + j++; + i += 2; + } + } + } while (i < input_length); + preprocessed[j] = '\0'; + + return; +} + +int png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) +{ + int textdone, main_width, comp_offset, large_bar_count; + char textpart[10], addon[6]; + float addon_text_posn, preset_height, large_bar_height; + int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height; + char *pixelbuf; + int addon_latch = 0; + int this_row, block_width, plot_height, plot_yposn, textpos; + float row_height, row_posn; + int error_number; + int default_text_posn; + int next_yposn; +#ifndef _MSC_VER + unsigned char local_text[ustrlen(symbol->text) + 1]; +#else + unsigned char* local_text = (unsigned char*)_alloca(ustrlen(symbol->text) + 1); +#endif + + if(symbol->show_hrt != 0) { + to_latin1(symbol->text, local_text); + } else { + local_text[0] = '\0'; + } + + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + row_height = 0; + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for(i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if(symbol->row_height[i] == 0) { + large_bar_count++; + } + } + + if (large_bar_count == 0) { + symbol->height = preset_height; + large_bar_height = 10; + } else { + large_bar_height = (symbol->height - preset_height) / large_bar_count; + } + + while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch(ustrlen(local_text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if(is_extendable(symbol->symbology)) { + for(i = 0; i < ustrlen(local_text); i++) { + if (latch == 1) { + addon[r] = local_text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if(ustrlen(local_text) != 0) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + image_width = 2 * (symbol->width + xoffset + xoffset); + image_height = 2 * (symbol->height + textoffset + yoffset + yoffset); + + if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + printf("Insufficient memory for pixel buffer"); + return ERROR_ENCODING_PROBLEM; + } else { + for(i = 0; i < (image_width * image_height); i++) { + *(pixelbuf + i) = '0'; + } + } + + if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + default_text_posn = image_height - 17; + } else { + default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width; + } + + row_posn = textoffset + yoffset; + next_yposn = textoffset + yoffset; + row_height = 0; + + /* Plot the body of the symbol to the pixel buffer */ + for(r = 0; r < symbol->rows; r++) { + this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ + row_posn += row_height; + plot_yposn = next_yposn; + if(symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + next_yposn = (int)(row_posn + row_height); + plot_height = next_yposn - plot_yposn; + + i = 0; + if(module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if((addon_latch == 0) && (r == 0) && (i > main_width)) { + plot_height = (int)(row_height - 5.0); + plot_yposn = (int)(row_posn - 5.0); + addon_text_posn = row_posn + row_height - 8.0; + addon_latch = 1; + } + if(latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + + xoffset += comp_offset; + + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch(ustrlen(local_text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i]; + } + textpart[4] = '\0'; + textpos = 2 * (17 + xoffset); + + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i + 4]; + } + textpart[4] = '\0'; + textpos = 2 * (50 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 86); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 100); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = 2 * (-7 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 2 * (24 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 7]; + } + textpart[6] = '\0'; + textpos = 2 * (71 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 114); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 128); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = 2 * (-5 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[5] = '\0'; + textpos = 2 * (27 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 6]; + } + textpart[6] = '\0'; + textpos = 2 * (68 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textpart[0] = symbol->text[11]; + textpart[1] = '\0'; + textpos = 2 * (100 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 116); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 130); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); + + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = 2 * (-5 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 2 * (24 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textpart[0] = symbol->text[7]; + textpart[1] = '\0'; + textpos = 2 * (55 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, image_width, image_height); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 70); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 84); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, image_width, image_height); + break; + } + + } + + xoffset -= comp_offset; + + /* Put boundary bars or box around symbol */ + if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + if((symbol->symbology != BARCODE_CODABLOCKF) && (symbol->symbology != BARCODE_HIBC_BLOCKF)) { + /* boundary bars */ + draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); + if((symbol->output_options & BARCODE_BIND) != 0) { + if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + 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); + } + } + } + } else { + /* boundary bars */ + draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); + if(symbol->rows > 1) { + /* row binding */ + for(r = 1; r < symbol->rows; r++) { + draw_bar(pixelbuf, (xoffset + 11) * 2, (symbol->width - 24) * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height); + } + } + } + } + + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); + draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); + } + + /* Put the human readable text at the bottom */ + if((textdone == 0) && (ustrlen(local_text) != 0)) { + textpos = (image_width / 2); + draw_string(pixelbuf, (char*)local_text, textpos, default_text_posn, image_width, image_height); + } + + error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); + free(pixelbuf); + return error_number; +} + +#ifndef NO_PNG +int png_handle(struct zint_symbol *symbol, int rotate_angle) +{ + int error; + + if(symbol->symbology == BARCODE_MAXICODE) { + error = maxi_png_plot(symbol, rotate_angle, PNG_DATA); + } else { + error = png_plot(symbol, rotate_angle, PNG_DATA); + } + + return error; +} +#endif /* NO_PNG */ + +int bmp_handle(struct zint_symbol *symbol, int rotate_angle) +{ + int error; + + if(symbol->symbology == BARCODE_MAXICODE) { + error = maxi_png_plot(symbol, rotate_angle, BMP_DATA); + } else { + error = png_plot(symbol, rotate_angle, BMP_DATA); + } + + return error; +} + diff --git a/backend/postal.c b/backend/postal.c new file mode 100644 index 00000000..2dda84c1 --- /dev/null +++ b/backend/postal.c @@ -0,0 +1,603 @@ +/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */ + +/* Zint - A barcode generating program using libpng + Copyright (C) 2008 Robin Stuart + Including bug fixes by Bryan Hatton + + 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 +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" + +#define DAFTSET "DAFT" +#define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define KASUTSET "1234567890-abcdefgh" +#define CHKASUTSET "0123456789-abcdefgh" +#define SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +/* PostNet number encoding table - In this table L is long as S is short */ +static char *PNTable[10] = {"LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL", + "LSSLS", "LSLSS"}; +static char *PLTable[10] = {"SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS", + "SLLSL", "SLSLL"}; + +static char *RoyalValues[36] = {"11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25", + "20", "31", "32", "33", "34", "35", "30", "41", "42", "43", "44", "45", "40", "51", "52", + "53", "54", "55", "50", "01", "02", "03", "04", "05", "00"}; + +/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */ +static char *RoyalTable[36] = {"3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021", + "2130", "2121", "2031", "3102", "3012", "3003", "2112", "2103", "2013", "1320", "1230", + "1221", "0330", "0321", "0231", "1302", "1212", "1203", "0312", "0303", "0213", "1122", + "1032", "1023", "0132", "0123", "0033"}; + +static char *FlatTable[10] = {"0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711", + "0810"}; + +static char *KoreaTable[10] = {"1313150613", "0713131313", "0417131313", "1506131313", + "0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713"}; + +static char *JapanTable[19] = {"114", "132", "312", "123", "141", "321", "213", "231", "411", "144", + "414", "324", "342", "234", "432", "243", "423", "441", "111"}; + +int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) +{ + /* Handles the PostNet system used for Zip codes in the US */ + unsigned int i, sum, check_digit; + int error_number; + + error_number = 0; + + if(length > 38) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + sum = 0; + + /* start character */ + strcpy(dest, "L"); + + for (i=0; i < length; i++) + { + lookup(NEON, PNTable, source[i], dest); + sum += ctoi(source[i]); + } + + check_digit = (10 - (sum % 10)) % 10; + concat(dest, PNTable[check_digit]); + + /* stop character */ + concat (dest, "L"); + + return error_number; +} + +int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Puts PostNet barcodes into the pattern matrix */ + char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ + unsigned int loopey, h; + int writer; + int error_number; + + error_number = 0; + + error_number = postnet(symbol, source, height_pattern, length); + if(error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if(height_pattern[loopey] == 'L') + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + writer += 3; + } + symbol->row_height[0] = 6; + symbol->row_height[1] = 6; + symbol->rows = 2; + symbol->width = writer - 1; + + return error_number; +} + +int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) +{ + /* Handles the PLANET system used for item tracking in the US */ + unsigned int i, sum, check_digit; + int error_number; + + error_number = 0; + + if(length > 38) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + sum = 0; + + /* start character */ + strcpy(dest, "L"); + + for (i=0; i < length; i++) + { + lookup(NEON, PLTable, source[i], dest); + sum += ctoi(source[i]); + } + + check_digit = (10 - (sum % 10)) % 10; + concat(dest, PLTable[check_digit]); + + /* stop character */ + concat (dest, "L"); + + return error_number; +} + +int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Puts PLANET barcodes into the pattern matrix */ + char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ + unsigned int loopey, h; + int writer; + int error_number; + + error_number = 0; + + error_number = planet(symbol, source, height_pattern, length); + if(error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if(height_pattern[loopey] == 'L') + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + writer += 3; + } + symbol->row_height[0] = 6; + symbol->row_height[1] = 6; + symbol->rows = 2; + symbol->width = writer - 1; + return error_number; +} + +int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Korean Postal Authority */ + + int total, loop, check, zeroes, error_number; + char localstr[8], dest[80]; + + error_number = 0; + if(length > 6) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + zeroes = 6 - length; + memset(localstr, '0', zeroes); + strcpy(localstr + zeroes, (char *)source); + + total = 0; + for(loop = 0; loop < 6; loop++) { + total += ctoi(localstr[loop]); + } + check = 10 - (total % 10); + if(check == 10) { check = 0; } + localstr[6] = itoc(check); + localstr[7] = '\0'; + *dest = '\0'; + for(loop = 5; loop >= 0; loop--) { + lookup(NEON, KoreaTable, localstr[loop], dest); + } + lookup(NEON, KoreaTable, localstr[6], dest); + expand(symbol, dest); + ustrcpy(symbol->text, (unsigned char*)localstr); + return error_number; +} + +int fim(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* The simplest barcode symbology ever! Supported by MS Word, so here it is! */ + /* glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */ + + char dest[16] = { 0 }; + + if(length > 1) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + switch((char)source[0]) { + case 'a': + case 'A': + strcpy(dest, "111515111"); + break; + case 'b': + case 'B': + strcpy(dest, "13111311131"); + break; + case 'c': + case 'C': + strcpy(dest, "11131313111"); + break; + case 'd': + case 'D': + strcpy(dest, "1111131311111"); + break; + default: + strcpy(symbol->errtxt, "Invalid characters in data"); + return ERROR_INVALID_DATA; + break; + } + + expand(symbol, dest); + return 0; +} + +char rm4scc(char source[], unsigned char dest[], int length) +{ + /* Handles the 4 State barcodes used in the UK by Royal Mail */ + unsigned int i; + int top, bottom, row, column, check_digit; + char values[3], set_copy[] = KRSET; + + top = 0; + bottom = 0; + + /* start character */ + strcpy((char*)dest, "1"); + + for (i = 0; i < length; i++) { + lookup(KRSET, RoyalTable, source[i], (char*)dest); + strcpy(values, RoyalValues[posn(KRSET, source[i])]); + top += ctoi(values[0]); + bottom += ctoi(values[1]); + } + + /* Calculate the check digit */ + row = (top % 6) - 1; + column = (bottom % 6) - 1; + if(row == -1) { row = 5; } + if(column == -1) { column = 5; } + check_digit = (6 * row) + column; + concat((char*)dest, RoyalTable[check_digit]); + + /* stop character */ + concat ((char*)dest, "0"); + + return set_copy[check_digit]; +} + +int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Puts RM4SCC into the data matrix */ + char height_pattern[200], check; + unsigned int loopey, h; + int writer; + int error_number; + strcpy(height_pattern, ""); + + error_number = 0; + + if(length > 120) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(KRSET, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + check = rm4scc((char*)source, (unsigned char*)height_pattern, length); + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 4; + symbol->row_height[1] = 2; + symbol->row_height[2] = 4; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Handles Dutch Post TNT KIX symbols */ + /* The same as RM4SCC but without check digit */ + /* Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */ + char height_pattern[50], localstr[13]; + unsigned int loopey; + int writer, i, h; + int error_number; /* zeroes; */ + strcpy(height_pattern, ""); + + error_number = 0; + + if(length > 11) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(KRSET, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* Add leading zeroes */ + /* zeroes = 11 - length; + memset(localstr, '0', zeroes); + strcpy(localstr + zeroes, (char *)source);*/ + strcpy(localstr, (char *)source); + + /* Encode data */ + for (i = 0; i < 11; i++) { + lookup(KRSET, RoyalTable, localstr[i], height_pattern); + } + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 4; + symbol->row_height[1] = 2; + symbol->row_height[2] = 4; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +int daft_code(struct zint_symbol *symbol, unsigned char source[], int length) +{ + /* Handles DAFT Code symbols */ + /* Presumably 'daft' doesn't mean the same thing in Germany as it does in the UK! */ + char height_pattern[100]; + unsigned int loopey, h; + int writer, i, error_number; + strcpy(height_pattern, ""); + + error_number = 0; + if(length > 50) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + to_upper((unsigned char*)source); + error_number = is_sane(DAFTSET, (unsigned char*)source, length); + + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + for (i = 0; i < length; i++) { + if(source[i] == 'D') { concat(height_pattern, "2"); } + if(source[i] == 'A') { concat(height_pattern, "1"); } + if(source[i] == 'F') { concat(height_pattern, "0"); } + if(source[i] == 'T') { concat(height_pattern, "3"); } + } + + writer = 0; + h = strlen(height_pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) + { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 4; + symbol->row_height[1] = 2; + symbol->row_height[2] = 4; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Flattermarken - Not really a barcode symbology and (in my opinion) probably not much use + but it's supported by TBarCode so it's supported by Zint! */ + int loop, error_number; + char dest[512]; /* 90 * 4 + 1 ~ */ + + error_number = 0; + + if(length > 90) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + *dest = '\0'; + for(loop = 0; loop < length; loop++) { + lookup(NEON, FlatTable, source[loop], dest); + } + + expand(symbol, dest); + return error_number; +} + +int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) +{ /* Japanese Postal Code (Kasutama Barcode) */ + int error_number, h; + char pattern[69]; + int writer, loopey, inter_posn, i, sum, check; + char check_char; + char inter[23]; + +#ifndef _MSC_VER + char local_source[length + 1]; +#else + char* local_source = (char*)_alloca(length + 1); +#endif + + inter_posn = 0; + error_number = 0; + + strcpy(local_source, (char*)source); + for(i = 0; i < length; i++) { + local_source[i] = source[i]; + } + to_upper((unsigned char*)local_source); + error_number = is_sane(SHKASUTSET, (unsigned char*)local_source, length); + + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + memset(inter, 'd', 20);/* Pad character CC4 */ + inter[20] = '\0'; + + i = 0; + inter_posn = 0; + do { + if(((local_source[i] >= '0') && (local_source[i] <= '9')) || (local_source[i] == '-')) { + inter[inter_posn] = local_source[i]; + inter_posn++; + } else { + if((local_source[i] >= 'A') && (local_source[i] <= 'J')) { + inter[inter_posn] = 'a'; + inter[inter_posn + 1] = local_source[i] - 'A' + '0'; + inter_posn += 2; + } + if((local_source[i] >= 'K') && (local_source[i] <= 'T')) { + inter[inter_posn] = 'b'; + inter[inter_posn + 1] = local_source[i] - 'K' + '0'; + inter_posn += 2; + } + if((local_source[i] >= 'U') && (local_source[i] <= 'Z')) { + inter[inter_posn] = 'c'; + inter[inter_posn + 1] = local_source[i] - 'U' + '0'; + inter_posn += 2; + } + } + i++; + }while((i < length) && (inter_posn < 20)); + inter[20] = '\0'; + + strcpy(pattern, "13"); /* Start */ + + sum = 0; + for(i = 0; i < 20; i++) { + concat(pattern, JapanTable[posn(KASUTSET, inter[i])]); + sum += posn(CHKASUTSET, inter[i]); + /* printf("%c (%d)\n", inter[i], posn(CHKASUTSET, inter[i])); */ + } + + /* Calculate check digit */ + check = 19 - (sum % 19); + if(check == 19) { check = 0; } + if(check <= 9) { check_char = check + '0'; } + if(check == 10) { check_char = '-'; } + if(check >= 11) { check_char = (check - 11) + 'a'; } + concat(pattern, JapanTable[posn(KASUTSET, check_char)]); + /* printf("check %c (%d)\n", check_char, check); */ + + concat(pattern, "31"); /* Stop */ + + /* Resolve pattern to 4-state symbols */ + writer = 0; + h = strlen(pattern); + for(loopey = 0; loopey < h; loopey++) + { + if((pattern[loopey] == '2') || (pattern[loopey] == '1')) + { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if((pattern[loopey] == '3') || (pattern[loopey] == '1')) + { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 2; + symbol->row_height[1] = 2; + symbol->row_height[2] = 2; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} diff --git a/backend/ps.c b/backend/ps.c new file mode 100644 index 00000000..dc7ce9c2 --- /dev/null +++ b/backend/ps.c @@ -0,0 +1,778 @@ +/* ps.c - Post Script output */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include +#include "common.h" + +#define SSET "0123456789ABCDEF" + +/* This file has expanded quite a bit since version 1.5 in order to accomodate + the formatting rules for EAN and UPC symbols as set out in EN 797:1995 - the + down side of this support is that the code is now vertually unreadable! */ + +int ps_plot(struct zint_symbol *symbol) +{ + int i, block_width, latch, r, this_row; + float textpos, large_bar_height, preset_height, row_height, row_posn; + FILE *feps; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone, main_width; + char textpart[10], addon[6]; + int large_bar_count, comp_offset; + float addon_text_posn; + float scaler = symbol->scale; + float default_text_posn; + int plot_text = 1; + const char *locale = NULL; + + row_height=0; + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + + if((symbol->output_options & BARCODE_STDOUT) != 0) { + feps = stdout; + } else { + feps = fopen(symbol->outfile, "w"); + } + if(feps == NULL) { + strcpy(symbol->errtxt, "Could not open output file"); + return ERROR_FILE_ACCESS; + } + + /* sort out colour options */ + to_upper((unsigned char*)symbol->fgcolour); + to_upper((unsigned char*)symbol->bgcolour); + + if(strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + if(strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + locale = setlocale(LC_ALL, "C"); + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + red_ink = fgred / 256.0; + green_ink = fggrn / 256.0; + blue_ink = fgblu / 256.0; + red_paper = bgred / 256.0; + green_paper = bggrn / 256.0; + blue_paper = bgblu / 256.0; + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for(i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if(symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch(ustrlen(symbol->text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if(is_extendable(symbol->symbology)) { + for(i = 0; i < ustrlen(symbol->text); i++) { + if (latch == 1) { + addon[r] = symbol->text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) { + plot_text = 0; + } + if(plot_text) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + /* Start writing the header */ + fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); + fprintf(feps, "%%%%Creator: Zint %s\n", ZINT_VERSION); + if(ustrlen(symbol->text) != 0) { + fprintf(feps, "%%%%Title: %s\n",symbol->text); + } else { + fprintf(feps, "%%%%Title: Zint Generated Symbol\n"); + } + fprintf(feps, "%%%%Pages: 0\n"); + if(symbol->symbology != BARCODE_MAXICODE) { + fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); + } else { + fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler)); + } + fprintf(feps, "%%%%EndComments\n"); + + /* Definitions */ + fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n"); + fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n"); + fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n"); + fprintf(feps, "/TB { 2 copy } bind def\n"); + fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n"); + fprintf(feps, "/TE { pop pop } bind def\n"); + + fprintf(feps, "newpath\n"); + + /* Now the actual representation */ + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); + fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler); + + if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + default_text_posn = 0.5 * scaler; + } else { + default_text_posn = (symbol->border_width + 0.5) * scaler; + } + + if(symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode uses hexagons */ + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + + + textoffset = 0.0; + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); + } + + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler); + for(r = 0; r < symbol->rows; r++) { + for(i = 0; i < symbol->width; i++) { + if(module_is_set(symbol, r, i)) { + /* Dump a hexagon */ + my = ((symbol->rows - r - 1)) * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + if(r % 2 == 1) { + mx = (2.46 * i) + 1.23 + 1.23; + } else { + mx = (2.46 * i) + 1.23; + } + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); + } + } + } + } + + if(symbol->symbology != BARCODE_MAXICODE) { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + int addon_latch = 0; + + for(r = 0; r < symbol->rows; r++) { + this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ + if(symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for(i = 0; i < r; i++) { + if(symbol->row_height[symbol->rows - i - 1] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[symbol->rows - i - 1]; + } + } + row_posn += (textoffset + yoffset); + + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler); + i = 0; + if(module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if((addon_latch == 0) && (r == 0) && (i > main_width)) { + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler); + addon_text_posn = row_posn + row_height - 8.0; + addon_latch = 1; + } + if(latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + /* That's done the actual data area, everything else is human-friendly */ + + xoffset += comp_offset; + + if (plot_text) { + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || + (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch(ustrlen(symbol->text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i]; + } + textpart[4] = '\0'; + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 17; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i + 4]; + } + textpart[4] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 50; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 86; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 100; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = -7; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 7]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 71; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 114; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 128; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[5] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 27; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 6]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 68; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textpart[0] = symbol->text[11]; + textpart[1] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 100; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 116; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 130; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textpart[0] = symbol->text[7]; + textpart[1] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 55; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 70; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 84; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + } + } /* if (plot_text) */ + + xoffset -= comp_offset; + + switch(symbol->symbology) { + case BARCODE_CODABLOCKF: + case BARCODE_HIBC_BLOCKF: + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, xoffset * scaler, symbol->width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, xoffset * scaler, symbol->width * scaler); + if(symbol->rows > 1) { + /* row binding */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + for(r = 1; r < symbol->rows; r++) { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, (xoffset + 11) * scaler, (symbol->width - 24) * scaler); + } + } + break; + case BARCODE_MAXICODE: + /* Do nothing! (It's already been done) */ + break; + default: + if((symbol->output_options & BARCODE_BIND) != 0) { + if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + for(r = 1; r < symbol->rows; r++) { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler); + } + } + } + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); + } + break; + } + + /* Put the human readable text at the bottom */ + if(plot_text && (textdone == 0)) { + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = symbol->width / 2.0; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", symbol->text); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", symbol->text); + fprintf(feps, "setmatrix\n"); + } + fprintf(feps, "\nshowpage\n"); + + fclose(feps); + + if (locale) + setlocale(LC_ALL, locale); + + return error_number; +} + diff --git a/backend/qr.c b/backend/qr.c new file mode 100644 index 00000000..2d1833ad --- /dev/null +++ b/backend/qr.c @@ -0,0 +1,2464 @@ +/* qr.c Handles QR Code */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include +#include "sjis.h" +#include "qr.h" +#include "reedsol.h" + +int in_alpha(int glyph) { + /* Returns true if input glyph is in the Alphanumeric set */ + int retval = 0; + char cglyph = (char) glyph; + + if((cglyph >= '0') && (cglyph <= '9')) { + retval = 1; + } + if((cglyph >= 'A') && (cglyph <= 'Z')) { + retval = 1; + } + switch (cglyph) { + case ' ': + case '$': + case '%': + case '*': + case '+': + case '-': + case '.': + case '/': + case ':': + retval = 1; + break; + } + + return retval; +} + +void define_mode(char mode[], int jisdata[], int length, int gs1) +{ + /* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */ + int i, mlen, j; + + for(i = 0; i < length; i++) { + if(jisdata[i] > 0xff) { + mode[i] = 'K'; + } else { + mode[i] = 'B'; + if(in_alpha(jisdata[i])) { mode[i] = 'A'; } + if(gs1 && (jisdata[i] == '[')) { mode[i] = 'A'; } + if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { mode[i] = 'N'; } + } + } + + /* If less than 6 numeric digits together then don't use numeric mode */ + for(i = 0; i < length; i++) { + if(mode[i] == 'N') { + if(((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) { + mlen = 0; + while (((mlen + i) < length) && (mode[mlen + i] == 'N')) { + mlen++; + }; + if(mlen < 6) { + for(j = 0; j < mlen; j++) { + mode[i + j] = 'A'; + } + } + } + } + } + + /* If less than 4 alphanumeric characters together then don't use alphanumeric mode */ + for(i = 0; i < length; i++) { + if(mode[i] == 'A') { + if(((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) { + mlen = 0; + while (((mlen + i) < length) && (mode[mlen + i] == 'A')) { + mlen++; + }; + if(mlen < 6) { + for(j = 0; j < mlen; j++) { + mode[i + j] = 'B'; + } + } + } + } + } +} + +int estimate_binary_length(char mode[], int length, int gs1) +{ + /* Make an estimate (worst case scenario) of how long the binary string will be */ + int i, count = 0; + char current = 0; + int a_count = 0; + int n_count = 0; + + if(gs1) { count += 4; } + + for(i = 0; i < length; i++) { + if(mode[i] != current) { + switch(mode[i]) { + case 'K': count += 12 + 4; current = 'K'; break; + case 'B': count += 16 + 4; current = 'B'; break; + case 'A': count += 13 + 4; current = 'A'; a_count = 0; break; + case 'N': count += 14 + 4; current = 'N'; n_count = 0; break; + } + } + + switch(mode[i]) { + case 'K': count += 13; break; + case 'B': count += 8; break; + case 'A': + a_count++; + if((a_count % 2) == 0) { + count += 5; // 11 in total + a_count = 0; + } + else + count += 6; + break; + case 'N': + n_count++; + if((n_count % 3) == 0) { + count += 3; // 10 in total + n_count = 0; + } + else if ((n_count % 2) == 0) + count += 3; // 7 in total + else + count += 4; + break; + } + } + + return count; +} + +void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen) +{ + /* Convert input data to a binary stream and add padding */ + int position = 0, debug = 0; + int short_data_block_length, i, scheme; + char data_block, padbits; + int current_binlen, current_bytes; + int toggle, percent; + +#ifndef _MSC_VER + char binary[est_binlen + 12]; +#else + char* binary = (char *)_alloca(est_binlen + 12); +#endif + strcpy(binary, ""); + + if(gs1) { + concat(binary, "0101"); /* FNC1 */ + } + + if(version <= 9) { + scheme = 1; + } + if((version >= 10) && (version <= 26)) { + scheme = 2; + } + if(version >= 27) { + scheme = 3; + } + + if(debug) { + for(i = 0; i < length; i++) { + printf("%c", mode[i]); + } + printf("\n"); + } + + percent = 0; + + do { + data_block = mode[position]; + short_data_block_length = 0; + do { + short_data_block_length++; + } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block)); + + switch(data_block) { + case 'K': + /* Kanji mode */ + /* Mode indicator */ + concat(binary, "1000"); + + /* Character count indicator */ + switch(scheme) { + case 3: + if(short_data_block_length & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + case 2: + if(short_data_block_length & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(short_data_block_length & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + for(i = 0; i < short_data_block_length; i++) { + int jis = jisdata[position + i]; + int msb, lsb, prod; + + if(jis > 0x9fff) { jis -= 0xc140; } + msb = (jis & 0xff00) >> 4; + lsb = (jis & 0xff); + prod = (msb * 0xc0) + lsb; + + if(prod & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + + if(debug) { printf("0x%4X ", prod); } + } + + if(debug) { printf("\n"); } + + break; + case 'B': + /* Byte mode */ + /* Mode indicator */ + concat(binary, "0100"); + + /* Character count indicator */ + switch (scheme) { + case 3: + case 2: + if(short_data_block_length & 0x8000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x4000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x2000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(short_data_block_length & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + for(i = 0; i < short_data_block_length; i++) { + int byte = jisdata[position + i]; + + if(gs1 && (byte == '[')) { + byte = 0x1d; /* FNC1 */ + } + + if(byte & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + + if(debug) { printf("0x%4X ", byte); } + } + + if(debug) { printf("\n"); } + + break; + case 'A': + /* Alphanumeric mode */ + /* Mode indicator */ + concat(binary, "0010"); + + /* Character count indicator */ + switch (scheme) { + case 3: + if(short_data_block_length & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + case 2: + if(short_data_block_length & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(short_data_block_length & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + i = 0; + while ( i < short_data_block_length ) { + int count; + int first = 0, second = 0, prod; + + if(percent == 0) { + if(gs1 && (jisdata[position + i] == '%')) { + first = posn(RHODIUM, '%'); + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + i++; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + first = posn(RHODIUM, '%'); /* FNC1 */ + } else { + first = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 1; + i++; + prod = first; + + if(mode[position + i] == 'A') { + if(gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } + } + } else { + first = posn(RHODIUM, '%'); + count = 1; + i++; + prod = first; + percent = 0; + + if(mode[position + i] == 'A') { + if(gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } + } + + switch(count) { + case 2: + if(prod & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("0x%4X ", prod); } + }; + + if(debug) { printf("\n"); } + + break; + case 'N': + /* Numeric mode */ + /* Mode indicator */ + concat(binary, "0001"); + + /* Character count indicator */ + switch (scheme) { + case 3: + if(short_data_block_length & 0x2000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + case 2: + if(short_data_block_length & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(short_data_block_length & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(short_data_block_length & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + i = 0; + while ( i < short_data_block_length ) { + int count; + int first = 0, second = 0, third = 0, prod; + + first = posn(NEON, (char) jisdata[position + i]); + count = 1; + prod = first; + + if(mode[position + i + 1] == 'N') { + second = posn(NEON, (char) jisdata[position + i + 1]); + count = 2; + prod = (prod * 10) + second; + } + + if(mode[position + i + 2] == 'N') { + third = posn(NEON, (char) jisdata[position + i + 2]); + count = 3; + prod = (prod * 10) + third; + } + + switch(count) { + case 3: + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + case 2: + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("0x%4X (%d)", prod, prod); } + + i += count; + }; + + if(debug) { printf("\n"); } + + break; + } + + position += short_data_block_length; + } while (position < length - 1) ; + + /* Terminator */ + concat(binary, "0000"); + + current_binlen = strlen(binary); + padbits = 8 - (current_binlen % 8); + if(padbits == 8) { padbits = 0; } + current_bytes = (current_binlen + padbits) / 8; + + /* Padding bits */ + for(i = 0; i < padbits; i++) { + concat(binary, "0"); + } + + /* Put data into 8-bit codewords */ + for(i = 0; i < current_bytes; i++) { + datastream[i] = 0x00; + if(binary[i * 8] == '1') { datastream[i] += 0x80; } + if(binary[i * 8 + 1] == '1') { datastream[i] += 0x40; } + if(binary[i * 8 + 2] == '1') { datastream[i] += 0x20; } + if(binary[i * 8 + 3] == '1') { datastream[i] += 0x10; } + if(binary[i * 8 + 4] == '1') { datastream[i] += 0x08; } + if(binary[i * 8 + 5] == '1') { datastream[i] += 0x04; } + if(binary[i * 8 + 6] == '1') { datastream[i] += 0x02; } + if(binary[i * 8 + 7] == '1') { datastream[i] += 0x01; } + } + + /* Add pad codewords */ + toggle = 0; + for(i = current_bytes; i < target_binlen; i++) { + if(toggle == 0) { + datastream[i] = 0xec; + toggle = 1; + } else { + datastream[i] = 0x11; + toggle = 0; + } + } + + if(debug) { + for(i = 0; i < target_binlen; i++) { + printf("0x%2X ", datastream[i]); + } + printf("\n"); + } +} + +void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int blocks) +{ + /* Split data into blocks, add error correction and then interleave the blocks and error correction data */ + int ecc_cw = qr_total_codewords[version - 1] - data_cw; + int short_data_block_length = data_cw / blocks; + int qty_long_blocks = data_cw % blocks; + int qty_short_blocks = blocks - qty_long_blocks; + int ecc_block_length = ecc_cw / blocks; + int i, j, length_this_block, posn, debug = 0; + + +#ifndef _MSC_VER + unsigned char data_block[short_data_block_length + 2]; + unsigned char ecc_block[ecc_block_length + 2]; + int interleaved_data[data_cw + 2]; + int interleaved_ecc[ecc_cw + 2]; +#else + unsigned char* data_block = (unsigned char *)_alloca(short_data_block_length + 2); + unsigned char* ecc_block = (unsigned char *)_alloca(ecc_block_length + 2); + int* interleaved_data = (int *)_alloca((data_cw + 2) * sizeof(int)); + int* interleaved_ecc = (int *)_alloca((ecc_cw + 2) * sizeof(int)); +#endif + + posn = 0; + + for(i = 0; i < blocks; i++) { + if(i < qty_short_blocks) { length_this_block = short_data_block_length; } else { length_this_block = short_data_block_length + 1; } + + for(j = 0; j < ecc_block_length; j++) { + ecc_block[j] = 0; + } + + for(j = 0; j < length_this_block; j++) { + data_block[j] = (unsigned char) datastream[posn + j]; + } + + rs_init_gf(0x11d); + rs_init_code(ecc_block_length, 0); + rs_encode(length_this_block, data_block, ecc_block); + rs_free(); + + if(debug) { + printf("Block %d: ", i + 1); + for(j = 0; j < length_this_block; j++) { + printf("%2X ", data_block[j]); + } + if(i < qty_short_blocks) { + printf(" "); + } + printf(" // "); + for(j = 0; j < ecc_block_length; j++) { + printf("%2X ", ecc_block[ecc_block_length - j - 1]); + } + printf("\n"); + } + + for(j = 0; j < short_data_block_length; j++) { + interleaved_data[(j * blocks) + i] = (int) data_block[j]; + } + + if(i >= qty_short_blocks){ + interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length]; + } + + for(j = 0; j < ecc_block_length; j++) { + interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1]; + } + + posn += length_this_block; + } + + for(j = 0; j < data_cw; j++) { + fullstream[j] = interleaved_data[j]; + } + for(j = 0; j < ecc_cw; j++) { + fullstream[j + data_cw] = interleaved_ecc[j]; + } + + if(debug) { + printf("\nData Stream: \n"); + for(j = 0; j < (data_cw + ecc_cw); j++) { + printf("%2X ", fullstream[j]); + } + printf("\n"); + } +} + +void place_finder(unsigned char grid[], int size, int x, int y) +{ + int xp, yp; + + int finder[] = { + 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 0, 1, + 1, 0, 1, 1, 1, 0, 1, + 1, 0, 1, 1, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1 + }; + + for(xp = 0; xp < 7; xp++) { + for(yp = 0; yp < 7; yp++) { + if (finder[xp + (7 * yp)] == 1) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +void place_align(unsigned char grid[], int size, int x, int y) +{ + int xp, yp; + + int alignment[] = { + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 1, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1 + }; + + x -= 2; + y -= 2; /* Input values represent centre of pattern */ + + for(xp = 0; xp < 5; xp++) { + for(yp = 0; yp < 5; yp++) { + if (alignment[xp + (5 * yp)] == 1) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +void setup_grid(unsigned char* grid, int size, int version) +{ + int i, toggle = 1; + int loopsize, x, y, xcoord, ycoord; + + /* Add timing patterns */ + for(i = 0; i < size; i++) { + if(toggle == 1) { + grid[(6 * size) + i] = 0x21; + grid[(i * size) + 6] = 0x21; + toggle = 0; + } else { + grid[(6 * size) + i] = 0x20; + grid[(i * size) + 6] = 0x20; + toggle = 1; + } + } + + /* Add finder patterns */ + place_finder(grid, size, 0, 0); + place_finder(grid, size, 0, size - 7); + place_finder(grid, size, size - 7, 0); + + /* Add separators */ + for(i = 0; i < 7; i++) { + grid[(7 * size) + i] = 0x10; + grid[(i * size) + 7] = 0x10; + grid[(7 * size) + (size - 1 - i)] = 0x10; + grid[(i * size) + (size - 8)] = 0x10; + grid[((size - 8) * size) + i] = 0x10; + grid[((size - 1 - i) * size) + 7] = 0x10; + } + grid[(7 * size) + 7] = 0x10; + grid[(7 * size) + (size - 8)] = 0x10; + grid[((size - 8) * size) + 7] = 0x10; + + /* Add alignment patterns */ + if(version != 1) { + /* Version 1 does not have alignment patterns */ + + loopsize = qr_align_loopsize[version - 1]; + for(x = 0; x < loopsize; x++) { + for(y = 0; y < loopsize; y++) { + xcoord = qr_table_e1[((version - 2) * 7) + x]; + ycoord = qr_table_e1[((version - 2) * 7) + y]; + + if(!(grid[(ycoord * size) + xcoord] & 0x10)) { + place_align(grid, size, xcoord, ycoord); + } + } + } + } + + /* Reserve space for format information */ + for(i = 0; i < 8; i++) { + grid[(8 * size) + i] += 0x20; + grid[(i * size) + 8] += 0x20; + grid[(8 * size) + (size - 1 - i)] = 0x20; + grid[((size - 1 - i) * size) + 8] = 0x20; + } + grid[(8 * size) + 8] += 20; + grid[((size - 1 - 7) * size) + 8] = 0x21; /* Dark Module from Figure 25 */ + + /* Reserve space for version information */ + if(version >= 7) { + for(i = 0; i < 6; i++) { + grid[((size - 9) * size) + i] = 0x20; + grid[((size - 10) * size) + i] = 0x20; + grid[((size - 11) * size) + i] = 0x20; + grid[(i * size) + (size - 9)] = 0x20; + grid[(i * size) + (size - 10)] = 0x20; + grid[(i * size) + (size - 11)] = 0x20; + } + } +} + +int cwbit(int* datastream, int i) { + int word = i / 8; + int bit = i % 8; + int resultant = 0; + + switch(bit) { + case 0: if(datastream[word] & 0x80) { resultant = 1; } else { resultant = 0; } break; + case 1: if(datastream[word] & 0x40) { resultant = 1; } else { resultant = 0; } break; + case 2: if(datastream[word] & 0x20) { resultant = 1; } else { resultant = 0; } break; + case 3: if(datastream[word] & 0x10) { resultant = 1; } else { resultant = 0; } break; + case 4: if(datastream[word] & 0x08) { resultant = 1; } else { resultant = 0; } break; + case 5: if(datastream[word] & 0x04) { resultant = 1; } else { resultant = 0; } break; + case 6: if(datastream[word] & 0x02) { resultant = 1; } else { resultant = 0; } break; + case 7: if(datastream[word] & 0x01) { resultant = 1; } else { resultant = 0; } break; + } + + return resultant; +} + +void populate_grid(unsigned char* grid, int size, int* datastream, int cw) +{ + int direction = 1; /* up */ + int row = 0; /* right hand side */ + + int i, n, x, y; + + n = cw * 8; + y = size - 1; + i = 0; + do { + x = (size - 2) - (row * 2); + if(x < 6) + x--; /* skip over vertical timing pattern */ + + if(!(grid[(y * size) + (x + 1)] & 0xf0)) { + if (cwbit(datastream, i)) { + grid[(y * size) + (x + 1)] = 0x01; + } else { + grid[(y * size) + (x + 1)] = 0x00; + } + i++; + } + + if(i < n) { + if(!(grid[(y * size) + x] & 0xf0)) { + if (cwbit(datastream, i)) { + grid[(y * size) + x] = 0x01; + } else { + grid[(y * size) + x] = 0x00; + } + i++; + } + } + + if(direction) { y--; } else { y++; } + if(y == -1) { + /* reached the top */ + row++; + y = 0; + direction = 0; + } + if(y == size) { + /* reached the bottom */ + row++; + y = size - 1; + direction = 1; + } + } while (i < n); +} + +int evaluate(unsigned char *grid, int size, int pattern) +{ + int x, y, block; + int result = 0; + char state; + int p; + int dark_mods; + int percentage, k; + +#ifndef _MSC_VER + char local[size * size]; +#else + char* local = (char *)_alloca((size * size) * sizeof(char)); +#endif + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + switch(pattern) { + case 0: if (grid[(y * size) + x] & 0x01) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 1: if (grid[(y * size) + x] & 0x02) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 2: if (grid[(y * size) + x] & 0x04) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 3: if (grid[(y * size) + x] & 0x08) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 4: if (grid[(y * size) + x] & 0x10) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 5: if (grid[(y * size) + x] & 0x20) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 6: if (grid[(y * size) + x] & 0x40) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + case 7: if (grid[(y * size) + x] & 0x80) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; + } + } + } + + /* Test 1: Adjacent modules in row/column in same colour */ + /* Vertical */ + for(x = 0; x < size; x++) { + state = local[x]; + block = 0; + for(y = 0; y < size; y++) { + if(local[(y * size) + x] == state) { + block++; + } else { + if(block > 5) { + result += (3 + block); + } + block = 0; + state = local[(y * size) + x]; + } + } + if(block > 5) { + result += (3 + block); + } + } + + /* Horizontal */ + for(y = 0; y < size; y++) { + state = local[y * size]; + block = 0; + for(x = 0; x < size; x++) { + if(local[(y * size) + x] == state) { + block++; + } else { + if(block > 5) { + result += (3 + block); + } + block = 0; + state = local[(y * size) + x]; + } + } + if(block > 5) { + result += (3 + block); + } + } + + /* Test 2 is not implimented */ + + /* Test 3: 1:1:3:1:1 ratio pattern in row/column */ + /* Vertical */ + for(x = 0; x < size; x++) { + for(y = 0; y < (size - 7); y++) { + p = 0; + if(local[(y * size) + x] == '1') { p += 0x40; } + if(local[((y + 1) * size) + x] == '1') { p += 0x20; } + if(local[((y + 2) * size) + x] == '1') { p += 0x10; } + if(local[((y + 3) * size) + x] == '1') { p += 0x08; } + if(local[((y + 4) * size) + x] == '1') { p += 0x04; } + if(local[((y + 5) * size) + x] == '1') { p += 0x02; } + if(local[((y + 6) * size) + x] == '1') { p += 0x01; } + if(p == 0x5d) { + result += 40; + } + } + } + + /* Horizontal */ + for(y = 0; y < size; y++) { + for(x = 0; x < (size - 7); x++) { + p = 0; + if(local[(y * size) + x] == '1') { p += 0x40; } + if(local[(y * size) + x + 1] == '1') { p += 0x20; } + if(local[(y * size) + x + 2] == '1') { p += 0x10; } + if(local[(y * size) + x + 3] == '1') { p += 0x08; } + if(local[(y * size) + x + 4] == '1') { p += 0x04; } + if(local[(y * size) + x + 5] == '1') { p += 0x02; } + if(local[(y * size) + x + 6] == '1') { p += 0x01; } + if(p == 0x5d) { + result += 40; + } + } + } + + /* Test 4: Proportion of dark modules in entire symbol */ + dark_mods = 0; + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + if(local[(y * size) + x] == '1') { + dark_mods++; + } + } + } + percentage = 100 * (dark_mods / (size * size)); + if(percentage <= 50) { + k = ((100 - percentage) - 50) / 5; + } else { + k = (percentage - 50) / 5; + } + + result += 10 * k; + + return result; +} + + +int apply_bitmask(unsigned char *grid, int size) +{ + int x, y; + unsigned char p; + int pattern, penalty[8]; + int best_val, best_pattern; + int bit; + +#ifndef _MSC_VER + unsigned char mask[size * size]; + unsigned char eval[size * size]; +#else + unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); + unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); +#endif + + /* Perform data masking */ + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + mask[(y * size) + x] = 0x00; + + if (!(grid[(y * size) + x] & 0xf0)) { + if(((y + x) % 2) == 0) { mask[(y * size) + x] += 0x01; } + if((y % 2) == 0) { mask[(y * size) + x] += 0x02; } + if((x % 3) == 0) { mask[(y * size) + x] += 0x04; } + if(((y + x) % 3) == 0) { mask[(y * size) + x] += 0x08; } + if((((y / 2) + (x / 3)) % 2) == 0) { mask[(y * size) + x] += 0x10; } + if((((y * x) % 2) + ((y * x) % 3)) == 0) { mask[(y * size) + x] += 0x20; } + if(((((y * x) % 2) + ((y * x) % 3)) % 2) == 0) { mask[(y * size) + x] += 0x40; } + if(((((y + x) % 2) + ((y * x) % 3)) % 2) == 0) { mask[(y * size) + x] += 0x80; } + } + } + } + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; } + + eval[(y * size) + x] = mask[(y * size) + x] ^ p; + } + } + + + /* Evaluate result */ + for(pattern = 0; pattern < 8; pattern++) { + penalty[pattern] = evaluate(eval, size, pattern); + } + + best_pattern = 0; + best_val = penalty[0]; + for(pattern = 1; pattern < 8; pattern++) { + if(penalty[pattern] < best_val) { + best_pattern = pattern; + best_val = penalty[pattern]; + } + } + + /* Apply mask */ + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + bit = 0; + switch(best_pattern) { + case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break; + case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break; + case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break; + case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break; + case 4: if(mask[(y * size) + x] & 0x10) { bit = 1; } break; + case 5: if(mask[(y * size) + x] & 0x20) { bit = 1; } break; + case 6: if(mask[(y * size) + x] & 0x40) { bit = 1; } break; + case 7: if(mask[(y * size) + x] & 0x80) { bit = 1; } break; + } + if(bit == 1) { + if(grid[(y * size) + x] & 0x01) { + grid[(y * size) + x] = 0x00; + } else { + grid[(y * size) + x] = 0x01; + } + } + } + } + + return best_pattern; +} + +void add_format_info(unsigned char *grid, int size, int ecc_level, int pattern) +{ + /* Add format information to grid */ + + int format = pattern; + unsigned int seq; + int i; + + switch(ecc_level) { + case LEVEL_L: format += 0x08; break; + case LEVEL_Q: format += 0x18; break; + case LEVEL_H: format += 0x10; break; + } + + seq = qr_annex_c[format]; + + for(i = 0; i < 6; i++) { + grid[(i * size) + 8] += (seq >> i) & 0x01; + } + + for(i = 0; i < 8; i++) { + grid[(8 * size) + (size - i - 1)] += (seq >> i) & 0x01; + } + + for(i = 0; i < 6; i++) { + grid[(8 * size) + (5 - i)] += (seq >> (i + 9)) & 0x01; + } + + for(i = 0; i < 7; i++) { + grid[(((size - 7) + i) * size) + 8] += (seq >> (i + 8)) & 0x01; + } + + grid[(7 * size) + 8] += (seq >> 6) & 0x01; + grid[(8 * size) + 8] += (seq >> 7) & 0x01; + grid[(8 * size) + 7] += (seq >> 8) & 0x01; +} + +void add_version_info(unsigned char *grid, int size, int version) +{ + /* Add version information */ + int i; + + long int version_data = qr_annex_d[version - 7]; + for(i = 0; i < 6; i++) { + grid[((size - 11) * size) + i] += (version_data >> (17 - (i * 3))) & 0x01; + grid[((size - 10) * size) + i] += (version_data >> (16 - (i * 3))) & 0x01; + grid[((size - 9) * size) + i] += (version_data >> (15 - (i * 3))) & 0x01; + grid[(i * size) + (size - 11)] += (version_data >> (17 - (i * 3))) & 0x01; + grid[(i * size) + (size - 10)] += (version_data >> (16 - (i * 3))) & 0x01; + grid[(i * size) + (size - 9)] += (version_data >> (15 - (i * 3))) & 0x01; + } +} + +int qr_code(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int error_number, i, j, glyph, est_binlen; + int ecc_level, autosize, version, max_cw, target_binlen, blocks, size; + int bitmask, gs1; + +#ifndef _MSC_VER + int utfdata[length + 1]; + int jisdata[length + 1]; + char mode[length + 1]; +#else + int* utfdata = (int *)_alloca((length + 1) * sizeof(int)); + int* jisdata = (int *)_alloca((length + 1) * sizeof(int)); + char* mode = (char *)_alloca(length + 1); +#endif + + if(symbol->input_mode == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + + switch(symbol->input_mode) { + case DATA_MODE: + for(i = 0; i < length; i++) { + jisdata[i] = (int)source[i]; + } + break; + default: + /* Convert Unicode input to Shift-JIS */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if(error_number != 0) { return error_number; } + + for(i = 0; i < length; i++) { + if(utfdata[i] <= 0xff) { + jisdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if(sjis_lookup[j * 2] == utfdata[i]) { + glyph = sjis_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 6843) && (glyph == 0)); + if(glyph == 0) { + strcpy(symbol->errtxt, "Invalid character in input data"); + return ERROR_INVALID_DATA; + } + jisdata[i] = glyph; + } + } + break; + } + + define_mode(mode, jisdata, length, gs1); + est_binlen = estimate_binary_length(mode, length, gs1); + + ecc_level = LEVEL_L; + max_cw = 2956; + if((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) { + switch (symbol->option_1) { + case 1: ecc_level = LEVEL_L; max_cw = 2956; break; + case 2: ecc_level = LEVEL_M; max_cw = 2334; break; + case 3: ecc_level = LEVEL_Q; max_cw = 1666; break; + case 4: ecc_level = LEVEL_H; max_cw = 1276; break; + } + } + + if(est_binlen > (8 * max_cw)) { + strcpy(symbol->errtxt, "Input too long for selected error correction level"); + return ERROR_TOO_LONG; + } + + autosize = 40; + for(i = 39; i >= 0; i--) { + switch(ecc_level) { + case LEVEL_L: + if ((8 * qr_data_codewords_L[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_M: + if ((8 * qr_data_codewords_M[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_Q: + if ((8 * qr_data_codewords_Q[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_H: + if ((8 * qr_data_codewords_H[i]) >= est_binlen) { + autosize = i + 1; + } + break; + } + } + + if((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) { + if (symbol->option_2 > autosize) { + version = symbol->option_2; + } else { + version = autosize; + } + } else { + version = autosize; + } + + /* Ensure maxium error correction capacity */ + if(est_binlen <= qr_data_codewords_M[version - 1]) { ecc_level = LEVEL_M; } + if(est_binlen <= qr_data_codewords_Q[version - 1]) { ecc_level = LEVEL_Q; } + if(est_binlen <= qr_data_codewords_H[version - 1]) { ecc_level = LEVEL_H; } + + target_binlen = qr_data_codewords_L[version - 1]; blocks = qr_blocks_L[version - 1]; + switch(ecc_level) { + case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; blocks = qr_blocks_M[version - 1]; break; + case LEVEL_Q: target_binlen = qr_data_codewords_Q[version - 1]; blocks = qr_blocks_Q[version - 1]; break; + case LEVEL_H: target_binlen = qr_data_codewords_H[version - 1]; blocks = qr_blocks_H[version - 1]; break; + } + +#ifndef _MSC_VER + int datastream[target_binlen + 1]; + int fullstream[qr_total_codewords[version - 1] + 1]; +#else + int* datastream = (int *)_alloca((target_binlen + 1) * sizeof(int)); + int* fullstream = (int *)_alloca((qr_total_codewords[version - 1] + 1) * sizeof(int)); +#endif + + qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen); + add_ecc(fullstream, datastream, version, target_binlen, blocks); + + size = qr_sizes[version - 1]; +#ifndef _MSC_VER + unsigned char grid[size * size]; +#else + unsigned char* grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); +#endif + + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + setup_grid(grid, size, version); + populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]); + bitmask = apply_bitmask(grid, size); + add_format_info(grid, size, ecc_level, bitmask); + if(version >= 7) { + add_version_info(grid, size, version); + } + + symbol->width = size; + symbol->rows = size; + + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + if(grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} + +/* NOTE: From this point forward concerns Micro QR Code only */ + +int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, int *kanji_used, int *alphanum_used, int *byte_used) +{ + /* Convert input data to an "intermediate stage" where data is binary encoded but + control information is not */ + int position = 0, debug = 0; + int short_data_block_length, i; + char data_block; + char buffer[2]; + + strcpy(binary, ""); + + if(debug) { + for(i = 0; i < length; i++) { + printf("%c", mode[i]); + } + printf("\n"); + } + + do { + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + + data_block = mode[position]; + short_data_block_length = 0; + do { + short_data_block_length++; + } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block)); + + switch(data_block) { + case 'K': + /* Kanji mode */ + /* Mode indicator */ + concat(binary, "K"); + *kanji_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + concat(binary, buffer); + + if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + for(i = 0; i < short_data_block_length; i++) { + int jis = jisdata[position + i]; + int msb, lsb, prod; + + if(jis > 0x9fff) { jis -= 0xc140; } + msb = (jis & 0xff00) >> 4; + lsb = (jis & 0xff); + prod = (msb * 0xc0) + lsb; + + if(prod & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + + if(debug) { printf("0x%4X ", prod); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + } + + if(debug) { printf("\n"); } + + break; + case 'B': + /* Byte mode */ + /* Mode indicator */ + concat(binary, "B"); + *byte_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + concat(binary, buffer); + + if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + for(i = 0; i < short_data_block_length; i++) { + int byte = jisdata[position + i]; + + if(byte & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(byte & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + + if(debug) { printf("0x%4X ", byte); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + } + + if(debug) { printf("\n"); } + + break; + case 'A': + /* Alphanumeric mode */ + /* Mode indicator */ + concat(binary, "A"); + *alphanum_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + concat(binary, buffer); + + if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + i = 0; + while ( i < short_data_block_length ) { + int count; + int first = 0, second = 0, prod; + + first = posn(RHODIUM, (char) jisdata[position + i]); + count = 1; + prod = first; + + if(mode[position + i + 1] == 'A') { + second = posn(RHODIUM, (char) jisdata[position + i + 1]); + count = 2; + prod = (first * 45) + second; + } + + switch(count) { + case 2: + if(prod & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("0x%4X ", prod); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + + i += 2; + }; + + if(debug) { printf("\n"); } + + break; + case 'N': + /* Numeric mode */ + /* Mode indicator */ + concat(binary, "N"); + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + concat(binary, buffer); + + if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); } + + /* Character representation */ + i = 0; + while ( i < short_data_block_length ) { + int count; + int first = 0, second = 0, third = 0, prod; + + first = posn(NEON, (char) jisdata[position + i]); + count = 1; + prod = first; + + if(mode[position + i + 1] == 'N') { + second = posn(NEON, (char) jisdata[position + i + 1]); + count = 2; + prod = (prod * 10) + second; + } + + if(mode[position + i + 2] == 'N') { + third = posn(NEON, (char) jisdata[position + i + 2]); + count = 3; + prod = (prod * 10) + third; + } + + switch(count) { + case 3: + if(prod & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + case 2: + if(prod & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + case 1: + if(prod & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + } + + if(debug) { printf("0x%4X (%d)", prod, prod); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + + i += 3; + }; + + if(debug) { printf("\n"); } + + break; + } + + position += short_data_block_length; + } while (position < length - 1) ; + + return 0; +} + +void get_bitlength(int count[], char stream[]) { + int length, i; + + length = strlen(stream); + + for(i = 0; i < 4; i++) { + count[i] = 0; + } + + i = 0; + do { + if((stream[i] == '0') || (stream[i] == '1')) { + count[0]++; + count[1]++; + count[2]++; + count[3]++; + i++; + } else { + switch(stream[i]) { + case 'K': + count[2] += 5; + count[3] += 7; + i += 2; + break; + case 'B': + count[2] += 6; + count[3] += 8; + i += 2; + break; + case 'A': + count[1] += 4; + count[2] += 6; + count[3] += 8; + i += 2; + break; + case 'N': + count[0] += 3; + count[1] += 5; + count[2] += 7; + count[3] += 9; + i += 2; + break; + } + } + } while (i < length); +} + +void microqr_expand_binary(char binary_stream[], char full_stream[], int version) +{ + int i, length; + + length = strlen(binary_stream); + + i = 0; + do { + switch(binary_stream[i]) { + case '1': concat(full_stream, "1"); i++; break; + case '0': concat(full_stream, "0"); i++; break; + case 'N': + /* Numeric Mode */ + /* Mode indicator */ + switch(version) { + case 1: concat(full_stream, "0"); break; + case 2: concat(full_stream, "00"); break; + case 3: concat(full_stream, "000"); break; + } + + /* Character count indicator */ + switch(version) { + case 3: + if(binary_stream[i + 1] & 0x20) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 2: + if(binary_stream[i + 1] & 0x10) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 1: + if(binary_stream[i + 1] & 0x08) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 0: + if(binary_stream[i + 1] & 0x04) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x02) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x01) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + } + + i += 2; + break; + case 'A': + /* Alphanumeric Mode */ + /* Mode indicator */ + switch(version) { + case 1: concat(full_stream, "1"); break; + case 2: concat(full_stream, "01"); break; + case 3: concat(full_stream, "001"); break; + } + + /* Character count indicator */ + switch(version) { + case 3: + if(binary_stream[i + 1] & 0x10) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 2: + if(binary_stream[i + 1] & 0x08) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 1: + if(binary_stream[i + 1] & 0x04) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x02) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x01) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + } + + i += 2; + break; + case 'B': + /* Byte Mode */ + /* Mode indicator */ + switch(version) { + case 2: concat(full_stream, "10"); break; + case 3: concat(full_stream, "010"); break; + } + + /* Character count indicator */ + switch(version) { + case 3: + if(binary_stream[i + 1] & 0x10) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 2: + if(binary_stream[i + 1] & 0x08) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x04) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x02) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x01) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + } + + i += 2; + break; + case 'K': + /* Kanji Mode */ + /* Mode indicator */ + switch(version) { + case 2: concat(full_stream, "11"); break; + case 3: concat(full_stream, "011"); break; + } + + /* Character count indicator */ + switch(version) { + case 3: + if(binary_stream[i + 1] & 0x08) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + case 2: + if(binary_stream[i + 1] & 0x04) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x02) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + if(binary_stream[i + 1] & 0x01) { concat(full_stream, "1"); } else { concat(full_stream, "0"); } + } + + i += 2; + break; + } + + } while (i < length); +} + +void micro_qr_m1(char binary_data[]) +{ + int i, latch; + int bits_total, bits_left, remainder; + int data_codewords, ecc_codewords; + unsigned char data_blocks[4], ecc_blocks[3]; + + bits_total = 20; + latch = 0; + + /* Add terminator */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 3) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } else { + concat(binary_data, "000"); + } + + if(latch == 0) { + /* Manage last (4-bit) block */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 4) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } + } + + if(latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if(remainder == 8) { remainder = 0; } + for(i = 0; i < remainder; i++) { + concat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - strlen(binary_data); + if(bits_left > 4) { + remainder = (bits_left - 4) / 8; + for(i = 0; i < remainder; i++) { + if((i % 2) == 0) { concat(binary_data, "11101100"); } + if((i % 2) == 1) { concat(binary_data, "00010001"); } + } + } + concat(binary_data, "0000"); + } + + data_codewords = 3; + ecc_codewords = 2; + + /* Copy data into codewords */ + for(i = 0; i < (data_codewords - 1); i++) { + data_blocks[i] = 0; + if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } + if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } + if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } + if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } + if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } + if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } + if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } + if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } + } + data_blocks[2] = 0; + if(binary_data[16] == '1') { data_blocks[2] += 0x08; } + if(binary_data[17] == '1') { data_blocks[2] += 0x04; } + if(binary_data[18] == '1') { data_blocks[2] += 0x02; } + if(binary_data[19] == '1') { data_blocks[2] += 0x01; } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords,data_blocks,ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for(i = 0; i < ecc_codewords; i++) { + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + } +} + +void micro_qr_m2(char binary_data[], int ecc_mode) +{ + int i, latch; + int bits_total, bits_left, remainder; + int data_codewords, ecc_codewords; + unsigned char data_blocks[6], ecc_blocks[7]; + + latch = 0; + + if(ecc_mode == LEVEL_L) { bits_total = 40; } + if(ecc_mode == LEVEL_M) { bits_total = 32; } + + /* Add terminator */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 5) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } else { + concat(binary_data, "00000"); + } + + if(latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if(remainder == 8) { remainder = 0; } + for(i = 0; i < remainder; i++) { + concat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - strlen(binary_data); + remainder = bits_left / 8; + for(i = 0; i < remainder; i++) { + if((i % 2) == 0) { concat(binary_data, "11101100"); } + if((i % 2) == 1) { concat(binary_data, "00010001"); } + } + } + + if(ecc_mode == LEVEL_L) { data_codewords = 5; ecc_codewords = 5; } + if(ecc_mode == LEVEL_M) { data_codewords = 4; ecc_codewords = 6; } + + /* Copy data into codewords */ + for(i = 0; i < data_codewords; i++) { + data_blocks[i] = 0; + if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } + if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } + if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } + if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } + if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } + if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } + if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } + if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords,data_blocks,ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for(i = 0; i < ecc_codewords; i++) { + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + } + + return; +} + +void micro_qr_m3(char binary_data[], int ecc_mode) +{ + int i, latch; + int bits_total, bits_left, remainder; + int data_codewords, ecc_codewords; + unsigned char data_blocks[12], ecc_blocks[9]; + + latch = 0; + + if(ecc_mode == LEVEL_L) { bits_total = 84; } + if(ecc_mode == LEVEL_M) { bits_total = 68; } + + /* Add terminator */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 7) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } else { + concat(binary_data, "0000000"); + } + + if(latch == 0) { + /* Manage last (4-bit) block */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 4) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } + } + + if(latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if(remainder == 8) { remainder = 0; } + for(i = 0; i < remainder; i++) { + concat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - strlen(binary_data); + if(bits_left > 4) { + remainder = (bits_left - 4) / 8; + for(i = 0; i < remainder; i++) { + if((i % 2) == 0) { concat(binary_data, "11101100"); } + if((i % 2) == 1) { concat(binary_data, "00010001"); } + } + } + concat(binary_data, "0000"); + } + + if(ecc_mode == LEVEL_L) { data_codewords = 11; ecc_codewords = 6; } + if(ecc_mode == LEVEL_M) { data_codewords = 9; ecc_codewords = 8; } + + /* Copy data into codewords */ + for(i = 0; i < (data_codewords - 1); i++) { + data_blocks[i] = 0; + if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } + if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } + if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } + if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } + if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } + if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } + if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } + if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } + } + + if(ecc_mode == LEVEL_L) { + data_blocks[11] = 0; + if(binary_data[80] == '1') { data_blocks[2] += 0x08; } + if(binary_data[81] == '1') { data_blocks[2] += 0x04; } + if(binary_data[82] == '1') { data_blocks[2] += 0x02; } + if(binary_data[83] == '1') { data_blocks[2] += 0x01; } + } + + if(ecc_mode == LEVEL_M) { + data_blocks[9] = 0; + if(binary_data[64] == '1') { data_blocks[2] += 0x08; } + if(binary_data[65] == '1') { data_blocks[2] += 0x04; } + if(binary_data[66] == '1') { data_blocks[2] += 0x02; } + if(binary_data[67] == '1') { data_blocks[2] += 0x01; } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords,data_blocks,ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for(i = 0; i < ecc_codewords; i++) { + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + } + + return; +} + +void micro_qr_m4(char binary_data[], int ecc_mode) +{ + int i, latch; + int bits_total, bits_left, remainder; + int data_codewords, ecc_codewords; + unsigned char data_blocks[17], ecc_blocks[15]; + + latch = 0; + + if(ecc_mode == LEVEL_L) { bits_total = 128; } + if(ecc_mode == LEVEL_M) { bits_total = 112; } + if(ecc_mode == LEVEL_Q) { bits_total = 80; } + + /* Add terminator */ + bits_left = bits_total - strlen(binary_data); + if(bits_left <= 9) { + for(i = 0; i < bits_left; i++) { + concat(binary_data, "0"); + } + latch = 1; + } else { + concat(binary_data, "000000000"); + } + + if(latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if(remainder == 8) { remainder = 0; } + for(i = 0; i < remainder; i++) { + concat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - strlen(binary_data); + remainder = bits_left / 8; + for(i = 0; i < remainder; i++) { + if((i % 2) == 0) { concat(binary_data, "11101100"); } + if((i % 2) == 1) { concat(binary_data, "00010001"); } + } + } + + if(ecc_mode == LEVEL_L) { data_codewords = 16; ecc_codewords = 8; } + if(ecc_mode == LEVEL_M) { data_codewords = 14; ecc_codewords = 10; } + if(ecc_mode == LEVEL_Q) { data_codewords = 10; ecc_codewords = 14; } + + /* Copy data into codewords */ + for(i = 0; i < data_codewords; i++) { + data_blocks[i] = 0; + if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } + if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } + if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } + if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } + if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } + if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } + if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } + if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords,data_blocks,ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for(i = 0; i < ecc_codewords; i++) { + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + } +} + +void micro_setup_grid(unsigned char* grid, int size) +{ + int i, toggle = 1; + + /* Add timing patterns */ + for(i = 0; i < size; i++) { + if(toggle == 1) { + grid[i] = 0x21; + grid[(i * size)] = 0x21; + toggle = 0; + } else { + grid[i] = 0x20; + grid[(i * size)] = 0x20; + toggle = 1; + } + } + + /* Add finder patterns */ + place_finder(grid, size, 0, 0); + + /* Add separators */ + for(i = 0; i < 7; i++) { + grid[(7 * size) + i] = 0x10; + grid[(i * size) + 7] = 0x10; + } + grid[(7 * size) + 7] = 0x10; + + + /* Reserve space for format information */ + for(i = 0; i < 8; i++) { + grid[(8 * size) + i] += 0x20; + grid[(i * size) + 8] += 0x20; + } + grid[(8 * size) + 8] += 20; +} + +void micro_populate_grid(unsigned char* grid, int size, char full_stream[]) +{ + int direction = 1; /* up */ + int row = 0; /* right hand side */ + + int i, n, x, y; + + n = strlen(full_stream); + y = size - 1; + i = 0; + do { + x = (size - 2) - (row * 2); + + if(!(grid[(y * size) + (x + 1)] & 0xf0)) { + if (full_stream[i] == '1') { + grid[(y * size) + (x + 1)] = 0x01; + } else { + grid[(y * size) + (x + 1)] = 0x00; + } + i++; + } + + if(i < n) { + if(!(grid[(y * size) + x] & 0xf0)) { + if (full_stream[i] == '1') { + grid[(y * size) + x] = 0x01; + } else { + grid[(y * size) + x] = 0x00; + } + i++; + } + } + + if(direction) { y--; } else { y++; } + if(y == 0) { + /* reached the top */ + row++; + y = 1; + direction = 0; + } + if(y == size) { + /* reached the bottom */ + row++; + y = size - 1; + direction = 1; + } + } while (i < n); +} + +int micro_evaluate(unsigned char *grid, int size, int pattern) +{ + int sum1, sum2, i, filter = 0, retval; + + switch(pattern) { + case 0: filter = 0x01; break; + case 1: filter = 0x02; break; + case 2: filter = 0x04; break; + case 3: filter = 0x08; break; + } + + sum1 = 0; + sum2 = 0; + for(i = 1; i < size; i++) { + if(grid[(i * size) + size - 1] & filter) { sum1++; } + if(grid[((size - 1) * size) + i] & filter) { sum2++; } + } + + if(sum1 <= sum2) { retval = (sum1 * 16) + sum2; } else { retval = (sum2 * 16) + sum1; } + + return retval; +} + +int micro_apply_bitmask(unsigned char *grid, int size) +{ + int x, y; + unsigned char p; + int pattern, value[8]; + int best_val, best_pattern; + int bit; + +#ifndef _MSC_VER + unsigned char mask[size * size]; + unsigned char eval[size * size]; +#else + unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); + unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); +#endif + + /* Perform data masking */ + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + mask[(y * size) + x] = 0x00; + + if (!(grid[(y * size) + x] & 0xf0)) { + if((y % 2) == 0) { mask[(y * size) + x] += 0x01; } + if((((y / 2) + (x / 3)) % 2) == 0) { mask[(y * size) + x] += 0x02; } + if(((((y * x) % 2) + ((y * x) % 3)) % 2) == 0) { mask[(y * size) + x] += 0x04; } + if(((((y + x) % 2) + ((y * x) % 3)) % 2) == 0) { mask[(y * size) + x] += 0x08; } + } + } + } + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; } + + eval[(y * size) + x] = mask[(y * size) + x] ^ p; + } + } + + + /* Evaluate result */ + for(pattern = 0; pattern < 8; pattern++) { + value[pattern] = micro_evaluate(eval, size, pattern); + } + + best_pattern = 0; + best_val = value[0]; + for(pattern = 1; pattern < 4; pattern++) { + if(value[pattern] > best_val) { + best_pattern = pattern; + best_val = value[pattern]; + } + } + + /* Apply mask */ + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + bit = 0; + switch(best_pattern) { + case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break; + case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break; + case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break; + case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break; + } + if(bit == 1) { + if(grid[(y * size) + x] & 0x01) { + grid[(y * size) + x] = 0x00; + } else { + grid[(y * size) + x] = 0x01; + } + } + } + } + + return best_pattern; +} + +int microqr(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int i, j, glyph, size; + char binary_stream[200]; + char full_stream[200]; + int utfdata[40]; + int jisdata[40]; + char mode[40]; + int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0; + int version_valid[4]; + int binary_count[4]; + int ecc_level, autoversion, version; + int n_count, a_count, bitmask, format, format_full; + + if(length > 35) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + + for(i = 0; i < 4; i++) { + version_valid[i] = 1; + } + + switch(symbol->input_mode) { + case DATA_MODE: + for(i = 0; i < length; i++) { + jisdata[i] = (int)source[i]; + } + break; + default: + /* Convert Unicode input to Shift-JIS */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if(error_number != 0) { return error_number; } + + for(i = 0; i < length; i++) { + if(utfdata[i] <= 0xff) { + jisdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if(sjis_lookup[j * 2] == utfdata[i]) { + glyph = sjis_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 6843) && (glyph == 0)); + if(glyph == 0) { + strcpy(symbol->errtxt, "Invalid character in input data"); + return ERROR_INVALID_DATA; + } + jisdata[i] = glyph; + } + } + break; + } + + define_mode(mode, jisdata, length, 0); + + n_count = 0; + a_count = 0; + for(i = 0; i < length; i++) { + if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { n_count++; } + if(in_alpha(jisdata[i])) { a_count++; } + } + + if(a_count == length) { + /* All data can be encoded in Alphanumeric mode */ + for(i = 0; i < length; i++) { + mode[i] = 'A'; + } + } + + if(n_count == length) { + /* All data can be encoded in Numeric mode */ + for(i = 0; i < length; i++) { + mode[i] = 'N'; + } + } + + error_number = micro_qr_intermediate(binary_stream, jisdata, mode, length, &kanji_used, &alphanum_used, &byte_used); + if(error_number != 0) { + strcpy(symbol->errtxt, "Input data too long"); + return error_number; + } + + get_bitlength(binary_count, binary_stream); + + /* Eliminate possivle versions depending on type of content */ + if(byte_used) { + version_valid[0] = 0; + version_valid[1] = 0; + } + + if(alphanum_used) { + version_valid[0] = 0; + } + + if(kanji_used) { + version_valid[0] = 0; + version_valid[1] = 0; + } + + /* Eliminate possible versions depending on length of binary data */ + if(binary_count[0] > 20) { version_valid[0] = 0; } + if(binary_count[1] > 40) { version_valid[1] = 0; } + if(binary_count[2] > 84) { version_valid[2] = 0; } + if(binary_count[3] > 128) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + + /* Eliminate possible versions depending on error correction level specified */ + ecc_level = LEVEL_L; + if((symbol->option_1 >= 1) && (symbol->option_2 <= 4)) { + ecc_level = symbol->option_1; + } + + if(ecc_level == LEVEL_H) { + strcpy(symbol->errtxt, "Error correction level H not available"); + return ERROR_INVALID_OPTION; + } + + if(ecc_level == LEVEL_Q) { + version_valid[0] = 0; + version_valid[1] = 0; + version_valid[2] = 0; + if(binary_count[3] > 80) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + } + + if(ecc_level == LEVEL_M) { + version_valid[0] = 0; + if(binary_count[1] > 32) { version_valid[1] = 0; } + if(binary_count[2] > 68) { version_valid[2] = 0; } + if(binary_count[3] > 112) { + strcpy(symbol->errtxt, "Input data too long"); + return ERROR_TOO_LONG; + } + } + + autoversion = 3; + if(version_valid[2]) { autoversion = 2; } + if(version_valid[1]) { autoversion = 1; } + if(version_valid[0]) { autoversion = 0; } + + version = autoversion; + /* Get version from user */ + if((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { + if(symbol->option_2 >= autoversion) { + version = symbol->option_2; + } + } + + /* If there is enough unused space then increase the error correction level */ + if(version == 3) { + if(binary_count[3] <= 112) { ecc_level = LEVEL_M; } + if(binary_count[3] <= 80) { ecc_level = LEVEL_Q; } + } + + if(version == 2) { + if(binary_count[2] <= 68) { ecc_level = LEVEL_M; } + } + + if(version == 1) { + if(binary_count[1] <= 32) { ecc_level = LEVEL_M; } + } + + strcpy(full_stream, ""); + microqr_expand_binary(binary_stream, full_stream, version); + + switch(version) { + case 0: micro_qr_m1(full_stream); break; + case 1: micro_qr_m2(full_stream, ecc_level); break; + case 2: micro_qr_m3(full_stream, ecc_level); break; + case 3: micro_qr_m4(full_stream, ecc_level); break; + } + + size = micro_qr_sizes[version]; +#ifndef _MSC_VER + unsigned char grid[size * size]; +#else + unsigned char* grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); +#endif + + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + micro_setup_grid(grid, size); + micro_populate_grid(grid, size, full_stream); + bitmask = micro_apply_bitmask(grid, size); + + /* Add format data */ + format = 0; + switch(version) { + case 1: switch(ecc_level) { + case 1: format = 1; break; + case 2: format = 2; break; + } + break; + case 2: switch(ecc_level) { + case 1: format = 3; break; + case 2: format = 4; break; + } + break; + case 3: switch(ecc_level) { + case 1: format = 5; break; + case 2: format = 6; break; + case 3: format = 7; break; + } + break; + } + + format_full = qr_annex_c1[(format << 2) + bitmask]; + + if(format_full & 0x4000) { grid[(8 * size) + 1] += 0x01; } + if(format_full & 0x2000) { grid[(8 * size) + 2] += 0x01; } + if(format_full & 0x1000) { grid[(8 * size) + 3] += 0x01; } + if(format_full & 0x800) { grid[(8 * size) + 4] += 0x01; } + if(format_full & 0x400) { grid[(8 * size) + 5] += 0x01; } + if(format_full & 0x200) { grid[(8 * size) + 6] += 0x01; } + if(format_full & 0x100) { grid[(8 * size) + 7] += 0x01; } + if(format_full & 0x80) { grid[(8 * size) + 8] += 0x01; } + if(format_full & 0x40) { grid[(7 * size) + 8] += 0x01; } + if(format_full & 0x20) { grid[(6 * size) + 8] += 0x01; } + if(format_full & 0x10) { grid[(5 * size) + 8] += 0x01; } + if(format_full & 0x08) { grid[(4 * size) + 8] += 0x01; } + if(format_full & 0x04) { grid[(3 * size) + 8] += 0x01; } + if(format_full & 0x02) { grid[(2 * size) + 8] += 0x01; } + if(format_full & 0x01) { grid[(1 * size) + 8] += 0x01; } + + symbol->width = size; + symbol->rows = size; + + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + if(grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} diff --git a/backend/qr.h b/backend/qr.h new file mode 100644 index 00000000..47576d55 --- /dev/null +++ b/backend/qr.h @@ -0,0 +1,156 @@ +/* qr.h Data for QR Code */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + Copyright (C) 2006 Kentaro Fukuchi + + 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. +*/ + +#define LEVEL_L 1 +#define LEVEL_M 2 +#define LEVEL_Q 3 +#define LEVEL_H 4 + +#define RHODIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + +/* From ISO/IEC 18004:2006 Table 7 */ +static int qr_data_codewords_L[] = { + 19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647, + 721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631, + 1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956 +}; + +static int qr_data_codewords_M[] = { + 16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507, + 563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267, + 1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334 +}; + +static int qr_data_codewords_Q[] = { + 13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367, + 397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911, + 985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666 +}; + +static int qr_data_codewords_H[] = { + 9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283, + 313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701, + 745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276 +}; + +static int qr_total_codewords[] = { + 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, + 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, + 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706 +}; + +static int qr_blocks_L[] = { + 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25 +}; + +static int qr_blocks_M[] = { + 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, + 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49 +}; + +static int qr_blocks_Q[] = { + 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, + 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68 +}; + +static int qr_blocks_H[] = { + 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, + 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81 +}; + +static int qr_sizes[] = { + 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, + 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177 +}; + +static int micro_qr_sizes[] = { + 11, 13, 15, 17 +}; + +static int qr_align_loopsize[] = { + 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 +}; + +static int qr_table_e1[] = { + 6, 18, 0, 0, 0, 0, 0, + 6, 22, 0, 0, 0, 0, 0, + 6, 26, 0, 0, 0, 0, 0, + 6, 30, 0, 0, 0, 0, 0, + 6, 34, 0, 0, 0, 0, 0, + 6, 22, 38, 0, 0, 0, 0, + 6, 24, 42, 0, 0, 0, 0, + 6, 26, 46, 0, 0, 0, 0, + 6, 28, 50, 0, 0, 0, 0, + 6, 30, 54, 0, 0, 0, 0, + 6, 32, 58, 0, 0, 0, 0, + 6, 34, 62, 0, 0, 0, 0, + 6, 26, 46, 66, 0, 0, 0, + 6, 26, 48, 70, 0, 0, 0, + 6, 26, 50, 74, 0, 0, 0, + 6, 30, 54, 78, 0, 0, 0, + 6, 30, 56, 82, 0, 0, 0, + 6, 30, 58, 86, 0, 0, 0, + 6, 34, 62, 90, 0, 0, 0, + 6, 28, 50, 72, 94, 0, 0, + 6, 26, 50, 74, 98, 0, 0, + 6, 30, 54, 78, 102, 0, 0, + 6, 28, 54, 80, 106, 0, 0, + 6, 32, 58, 84, 110, 0, 0, + 6, 30, 58, 86, 114, 0, 0, + 6, 34, 62, 90, 118, 0, 0, + 6, 26, 50, 74, 98, 122, 0, + 6, 30, 54, 78, 102, 126, 0, + 6, 26, 52, 78, 104, 130, 0, + 6, 30, 56, 82, 108, 134, 0, + 6, 34, 60, 86, 112, 138, 0, + 6, 30, 58, 86, 114, 142, 0, + 6, 34, 62, 90, 118, 146, 0, + 6, 30, 54, 78, 102, 126, 150, + 6, 24, 50, 76, 102, 128, 154, + 6, 28, 54, 80, 106, 132, 158, + 6, 32, 58, 84, 110, 136, 162, + 6, 26, 54, 82, 110, 138, 166, + 6, 30, 58, 86, 114, 142, 170 +}; + +static unsigned int qr_annex_c[] = { + /* Format information bit sequences */ + 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3, 0x7daa, 0x789d, + 0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b, + 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed +}; + +static long int qr_annex_d[] = { + /* Version information bit sequences */ + 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, + 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab, + 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, + 0x2542e, 0x26a64, 0x27541, 0x28c69 +}; + +static int qr_annex_c1[] = { + /* Micro QR Code format information */ + 0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, + 0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3, + 0x31d4, 0x3e8d, 0x3bba +}; \ No newline at end of file diff --git a/backend/reedsol.c b/backend/reedsol.c new file mode 100644 index 00000000..b37950b8 --- /dev/null +++ b/backend/reedsol.c @@ -0,0 +1,161 @@ +/** + * + * This is a simple Reed-Solomon encoder + * (C) Cliff Hones 2004 + * + * 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 2 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +// It is not written with high efficiency in mind, so is probably +// not suitable for real-time encoding. The aim was to keep it +// simple, general and clear. +// +// + +// Usage: +// First call rs_init_gf(poly) to set up the Galois Field parameters. +// Then call rs_init_code(size, index) to set the encoding size +// Then call rs_encode(datasize, data, out) to encode the data. +// +// These can be called repeatedly as required - but note that +// rs_init_code must be called following any rs_init_gf call. +// +// If the parameters are fixed, some of the statics below can be +// replaced with constants in the obvious way, and additionally +// malloc/free can be avoided by using static arrays of a suitable +// size. + +#include // only needed for debug (main) +#include // only needed for malloc/free +#include "reedsol.h" +static int gfpoly; +static int symsize; // in bits +static int logmod; // 2**symsize - 1 +static int rlen; + +static int *logt = NULL, *alog = NULL, *rspoly = NULL; + +// rs_init_gf(poly) initialises the parameters for the Galois Field. +// The symbol size is determined from the highest bit set in poly +// This implementation will support sizes up to 30 bits (though that +// will result in very large log/antilog tables) - bit sizes of +// 8 or 4 are typical +// +// The poly is the bit pattern representing the GF characteristic +// polynomial. e.g. for ECC200 (8-bit symbols) the polynomial is +// a**8 + a**5 + a**3 + a**2 + 1, which translates to 0x12d. + +void rs_init_gf(int poly) +{ + int m, b, p, v; + + // Find the top bit, and hence the symbol size + for (b = 1, m = 0; b <= poly; b <<= 1) + m++; + b >>= 1; + m--; + gfpoly = poly; + symsize = m; + + // Calculate the log/alog tables + logmod = (1 << m) - 1; + logt = (int *)malloc(sizeof(int) * (logmod + 1)); + alog = (int *)malloc(sizeof(int) * logmod); + + for (p = 1, v = 0; v < logmod; v++) { + alog[v] = p; + logt[p] = v; + p <<= 1; + if (p & b) + p ^= poly; + } +} + +// rs_init_code(nsym, index) initialises the Reed-Solomon encoder +// nsym is the number of symbols to be generated (to be appended +// to the input data). index is usually 1 - it is the index of +// the constant in the first term (i) of the RS generator polynomial: +// (x + 2**i)*(x + 2**(i+1))*... [nsym terms] +// For ECC200, index is 1. + +void rs_init_code(int nsym, int index) +{ + int i, k; + + rspoly = (int *)malloc(sizeof(int) * (nsym + 1)); + + rlen = nsym; + + rspoly[0] = 1; + for (i = 1; i <= nsym; i++) { + rspoly[i] = 1; + for (k = i - 1; k > 0; k--) { + if (rspoly[k]) + rspoly[k] = alog[(logt[rspoly[k]] + index) % logmod]; + rspoly[k] ^= rspoly[k - 1]; + } + rspoly[0] = alog[(logt[rspoly[0]] + index) % logmod]; + index++; + } +} + +void rs_encode(int len, unsigned char *data, unsigned char *res) +{ + int i, k, m; + for (i = 0; i < rlen; i++) + res[i] = 0; + for (i = 0; i < len; i++) { + m = res[rlen - 1] ^ data[i]; + for (k = rlen - 1; k > 0; k--) { + if (m && rspoly[k]) + res[k] = res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]; + else + res[k] = res[k - 1]; + } + if (m && rspoly[0]) + res[0] = alog[(logt[m] + logt[rspoly[0]]) % logmod]; + else + res[0] = 0; + } +} + +void rs_encode_long(int len, unsigned int *data, unsigned int *res) +{ /* The same as above but for larger bitlengths - Aztec code compatible */ + int i, k, m; + for (i = 0; i < rlen; i++) + res[i] = 0; + for (i = 0; i < len; i++) { + m = res[rlen - 1] ^ data[i]; + for (k = rlen - 1; k > 0; k--) { + if (m && rspoly[k]) + res[k] = res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]; + else + res[k] = res[k - 1]; + } + if (m && rspoly[0]) + res[0] = alog[(logt[m] + logt[rspoly[0]]) % logmod]; + else + res[0] = 0; + } +} + +void rs_free(void) +{ /* Free memory */ + free(logt); + free(alog); + free(rspoly); + rspoly = NULL; +} diff --git a/backend/reedsol.h b/backend/reedsol.h new file mode 100644 index 00000000..3a7f8efa --- /dev/null +++ b/backend/reedsol.h @@ -0,0 +1,40 @@ +/** + * + * This is a simple Reed-Solomon encoder + * (C) Cliff Hones 2004 + * + * 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 2 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __REEDSOL_H +#define __REEDSOL_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +extern void rs_init_gf(int poly); +extern void rs_init_code(int nsym, int index); +extern void rs_encode(int len, unsigned char *data, unsigned char *res); +extern void rs_encode_long(int len, unsigned int *data, unsigned int *res); +extern void rs_free(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __REEDSOL_H */ diff --git a/backend/rss.c b/backend/rss.c new file mode 100644 index 00000000..dd7bb4da --- /dev/null +++ b/backend/rss.c @@ -0,0 +1,2367 @@ +/* rss.c - Handles Reduced Space Symbology (GS1 DataBar) */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +/* The functions "combins" and "getRSSwidths" are copyright BSI and are + released with permission under the following terms: + + "Copyright subsists in all BSI publications. BSI also holds the copyright, in the + UK, of the international standardisation bodies. Except as + permitted under the Copyright, Designs and Patents Act 1988 no extract may be + reproduced, stored in a retrieval system or transmitted in any form or by any + means - electronic, photocopying, recording or otherwise - without prior written + permission from BSI. + + "This does not preclude the free use, in the course of implementing the standard, + of necessary details such as symbols, and size, type or grade designations. If these + details are to be used for any other purpose than implementation then the prior + written permission of BSI must be obtained." + + The date of publication for these functions is 30 November 2006 +*/ + +/* Includes numerous bugfixes thanks to Pablo Orduña @ the PIRAmIDE project */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "large.h" +#include "rss.h" +#include "gs1.h" + +/********************************************************************** +* combins(n,r): returns the number of Combinations of r selected from n: +* Combinations = n! / ((n - r)! * r!) +**********************************************************************/ +int combins(int n, int r) { + int i, j; + int maxDenom, minDenom; + int val; + + if (n-r > r) { + minDenom = r; + maxDenom = n-r; + } + else { + minDenom = n-r; + maxDenom = r; + } + val = 1; + j = 1; + for (i = n; i > maxDenom; i--) { + val *= i; + if (j <= minDenom) { + val /= j; + j++; + } + } + for (; j <= minDenom; j++) { + val /= j; + } + return(val); +} + +/********************************************************************** +* getRSSwidths +* routine to generate widths for RSS elements for a given value.# +* +* Calling arguments: +* val = required value +* n = number of modules +* elements = elements in a set (RSS-14 & Expanded = 4; RSS Limited = 7) +* maxWidth = maximum module width of an element +* noNarrow = 0 will skip patterns without a one module wide element +* +* Return: +* static int widths[] = element widths +**********************************************************************/ +void getRSSwidths(int val, int n, int elements, int maxWidth, int noNarrow) +{ + int bar; + int elmWidth; + int mxwElement; + int subVal, lessVal; + int narrowMask = 0; + for (bar = 0; bar < elements-1; bar++) + { + for(elmWidth = 1, narrowMask |= (1<= elements-bar-1)) + { + subVal -= combins(n-elmWidth-(elements-bar), elements-bar-2); + } + /* less combinations with elements > maxVal */ + if (elements-bar-1 > 1) + { + lessVal = 0; + for (mxwElement = n-elmWidth-(elements-bar-2); + mxwElement > maxWidth; + mxwElement--) + { + lessVal += combins(n-elmWidth-mxwElement-1, elements-bar-3); + } + subVal -= lessVal * (elements-1-bar); + } + else if (n-elmWidth > maxWidth) + { + subVal--; + } + val -= subVal; + if (val < 0) break; + } + val += subVal; + n -= elmWidth; + widths[bar] = elmWidth; + } + widths[bar] = n; + return; +} + +int rss14(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ /* GS1 DataBar-14 */ + int error_number = 0, i, j, mask; + short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; + int data_character[4], data_group[4], v_odd[4], v_even[4]; + int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer; + char latch, hrt[15], temp[32]; + int check_digit, count, separator_row; + + separator_row = 0; + + if(src_len > 13) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, src_len); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* make some room for a separator row for composite symbols */ + switch(symbol->symbology) { + case BARCODE_RSS14_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + break; + } + + for(i = 0; i < 112; i++) { + accum[i] = 0; + x_reg[i] = 0; + y_reg[i] = 0; + } + + for(i = 0; i < 4; i++) { + data_character[i] = 0; + data_group[i] = 0; + } + + binary_load(accum, (char*)source, src_len); + strcpy(temp, "10000000000000"); + if(symbol->option_1 == 2) { + /* Add symbol linkage flag */ + binary_load(y_reg, temp, strlen(temp)); + binary_add(accum, y_reg); + for(i = 0; i < 112; i++) { + y_reg[i] = 0; + } + } + + /* Calculate left and right pair values */ + strcpy(temp, "4537077"); + binary_load(x_reg, temp, strlen(temp)); + + for(i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for(i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + for(i = 0; i < 112; i++) { + left_reg[i] = y_reg[i]; + right_reg[i] = accum[i]; + } + + /* Calculate four data characters */ + strcpy(temp, "1597"); + binary_load(x_reg, temp, strlen(temp)); + for(i = 0; i < 112; i++) { + accum[i] = left_reg[i]; + } + + for(i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for(i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + data_character[0] = 0; + data_character[1] = 0; + mask = 0x2000; + for(i = 13; i >= 0; i--) { + if(y_reg[i] == 1) { + data_character[0] += mask; + } + if(accum[i] == 1) { + data_character[1] += mask; + } + mask = mask >> 1; + } + strcpy(temp, "1597"); + binary_load(x_reg, temp, strlen(temp)); + for(i = 0; i < 112; i++) { + accum[i] = right_reg[i]; + } + + for(i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for(i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + data_character[2] = 0; + data_character[3] = 0; + mask = 0x2000; + for(i = 13; i >= 0; i--) { + if(y_reg[i] == 1) { + data_character[2] += mask; + } + if(accum[i] == 1) { + data_character[3] += mask; + } + mask = mask >> 1; + } + + /* Calculate odd and even subset values */ + + if((data_character[0] >= 0) && (data_character[0] <= 160)) { data_group[0] = 0; } + if((data_character[0] >= 161) && (data_character[0] <= 960)) { data_group[0] = 1; } + if((data_character[0] >= 961) && (data_character[0] <= 2014)) { data_group[0] = 2; } + if((data_character[0] >= 2015) && (data_character[0] <= 2714)) { data_group[0] = 3; } + if((data_character[0] >= 2715) && (data_character[0] <= 2840)) { data_group[0] = 4; } + if((data_character[1] >= 0) && (data_character[1] <= 335)) { data_group[1] = 5; } + if((data_character[1] >= 336) && (data_character[1] <= 1035)) { data_group[1] = 6; } + if((data_character[1] >= 1036) && (data_character[1] <= 1515)) { data_group[1] = 7; } + if((data_character[1] >= 1516) && (data_character[1] <= 1596)) { data_group[1] = 8; } + if((data_character[3] >= 0) && (data_character[3] <= 335)) { data_group[3] = 5; } + if((data_character[3] >= 336) && (data_character[3] <= 1035)) { data_group[3] = 6; } + if((data_character[3] >= 1036) && (data_character[3] <= 1515)) { data_group[3] = 7; } + if((data_character[3] >= 1516) && (data_character[3] <= 1596)) { data_group[3] = 8; } + if((data_character[2] >= 0) && (data_character[2] <= 160)) { data_group[2] = 0; } + if((data_character[2] >= 161) && (data_character[2] <= 960)) { data_group[2] = 1; } + if((data_character[2] >= 961) && (data_character[2] <= 2014)) { data_group[2] = 2; } + if((data_character[2] >= 2015) && (data_character[2] <= 2714)) { data_group[2] = 3; } + if((data_character[2] >= 2715) && (data_character[2] <= 2840)) { data_group[2] = 4; } + + v_odd[0] = (data_character[0] - g_sum_table[data_group[0]]) / t_table[data_group[0]]; + v_even[0] = (data_character[0] - g_sum_table[data_group[0]]) % t_table[data_group[0]]; + v_odd[1] = (data_character[1] - g_sum_table[data_group[1]]) % t_table[data_group[1]]; + v_even[1] = (data_character[1] - g_sum_table[data_group[1]]) / t_table[data_group[1]]; + v_odd[3] = (data_character[3] - g_sum_table[data_group[3]]) % t_table[data_group[3]]; + v_even[3] = (data_character[3] - g_sum_table[data_group[3]]) / t_table[data_group[3]]; + v_odd[2] = (data_character[2] - g_sum_table[data_group[2]]) / t_table[data_group[2]]; + v_even[2] = (data_character[2] - g_sum_table[data_group[2]]) % t_table[data_group[2]]; + + + /* Use RSS subset width algorithm */ + for(i = 0; i < 4; i++) { + if((i == 0)||(i == 2)) { + getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 1); + data_widths[0][i] = widths[0]; + data_widths[2][i] = widths[1]; + data_widths[4][i] = widths[2]; + data_widths[6][i] = widths[3]; + getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 0); + data_widths[1][i] = widths[0]; + data_widths[3][i] = widths[1]; + data_widths[5][i] = widths[2]; + data_widths[7][i] = widths[3]; + } else { + getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 0); + data_widths[0][i] = widths[0]; + data_widths[2][i] = widths[1]; + data_widths[4][i] = widths[2]; + data_widths[6][i] = widths[3]; + getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 1); + data_widths[1][i] = widths[0]; + data_widths[3][i] = widths[1]; + data_widths[5][i] = widths[2]; + data_widths[7][i] = widths[3]; + } + } + + + checksum = 0; + /* Calculate the checksum */ + for(i = 0; i < 8; i++) { + checksum += checksum_weight[i] * data_widths[i][0]; + checksum += checksum_weight[i+8] * data_widths[i][1]; + checksum += checksum_weight[i+16] * data_widths[i][2]; + checksum += checksum_weight[i+24] * data_widths[i][3]; + } + checksum %= 79; + + /* Calculate the two check characters */ + if(checksum >= 8) { checksum++; } + if(checksum >= 72) { checksum++; } + c_left = checksum / 9; + c_right = checksum % 9; + + /* Put element widths together */ + total_widths[0] = 1; + total_widths[1] = 1; + total_widths[44] = 1; + total_widths[45] = 1; + for(i = 0; i < 8; i++) { + total_widths[i + 2] = data_widths[i][0]; + total_widths[i + 15] = data_widths[7 - i][1]; + total_widths[i + 23] = data_widths[i][3]; + total_widths[i + 36] = data_widths[7 - i][2]; + } + for(i = 0; i < 5; i++) { + total_widths[i + 10] = finder_pattern[i + (5 * c_left)]; + total_widths[i + 31] = finder_pattern[(4 - i) + (5 * c_right)]; + } + + /* Put this data into the symbol */ + if((symbol->symbology == BARCODE_RSS14) || (symbol->symbology == BARCODE_RSS14_CC)) { + writer = 0; + latch = '0'; + for(i = 0; i < 46; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if(symbol->width < writer) { symbol->width = writer; } + if(symbol->symbology == BARCODE_RSS14_CC) { + /* separator pattern for composite symbol */ + for(i = 4; i < 92; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); } + } + latch = '1'; + for(i = 16; i < 32; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + if(latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + latch = '1'; + for(i = 63; i < 78; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + if(latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + + count = 0; + check_digit = 0; + + /* Calculate check digit from Annex A and place human readable text */ + ustrcpy(symbol->text, (unsigned char*)"(01)"); + for(i = 0; i < 14; i++) { + hrt[i] = '0'; + } + for(i = 0; i < src_len; i++) { + hrt[12 - i] = source[src_len - i - 1]; + } + hrt[14] = '\0'; + + for (i = 0; i < 13; i++) + { + count += ctoi(hrt[i]); + + if ((i%2) == 0) + { + count += 2 * (ctoi(hrt[i])); + } + } + + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + hrt[13] = itoc(check_digit); + + uconcat(symbol->text, (unsigned char*)hrt); + } + + if((symbol->symbology == BARCODE_RSS14STACK) || (symbol->symbology == BARCODE_RSS14STACK_CC)) { + /* top row */ + writer = 0; + latch = '0'; + for(i = 0; i < 23; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + set_module(symbol, symbol->rows, writer); + unset_module(symbol, symbol->rows, writer + 1); + symbol->row_height[symbol->rows] = 5; + /* bottom row */ + symbol->rows = symbol->rows + 2; + set_module(symbol, symbol->rows, 0); + unset_module(symbol, symbol->rows, 1); + writer = 0; + latch = '1'; + for(i = 23; i < 46; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { + set_module(symbol, symbol->rows, writer + 2); + } else { + unset_module(symbol, symbol->rows, writer + 2); + } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + symbol->row_height[symbol->rows] = 7; + /* separator pattern */ + for(i = 4; i < 46; i++) { + if(module_is_set(symbol, symbol->rows - 2, i) == module_is_set(symbol, symbol->rows, i)) { + if(!(module_is_set(symbol, symbol->rows - 2, i))) { + set_module(symbol, symbol->rows - 1, i); + } + } else { + if(!(module_is_set(symbol, symbol->rows - 1, i - 1))) { + set_module(symbol, symbol->rows - 1, i); + } + } + } + symbol->row_height[symbol->rows - 1] = 1; + if(symbol->symbology == BARCODE_RSS14STACK_CC) { + /* separator pattern for composite symbol */ + for(i = 4; i < 46; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + latch = '1'; + for(i = 16; i < 32; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + if(latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + if(symbol->width < 50) { symbol->width = 50; } + } + + if((symbol->symbology == BARCODE_RSS14STACK_OMNI) || (symbol->symbology == BARCODE_RSS14_OMNI_CC)) { + /* top row */ + writer = 0; + latch = '0'; + for(i = 0; i < 23; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + set_module(symbol, symbol->rows, writer); + unset_module(symbol, symbol->rows, writer + 1); + /* bottom row */ + symbol->rows = symbol->rows + 4; + set_module(symbol, symbol->rows, 0); + unset_module(symbol, symbol->rows, 1); + writer = 0; + latch = '1'; + for(i = 23; i < 46; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer + 2); } else { unset_module(symbol, symbol->rows, writer + 2); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + /* middle separator */ + for(i = 5; i < 46; i += 2) { + set_module(symbol, symbol->rows - 2, i); + } + symbol->row_height[symbol->rows - 2] = 1; + /* top separator */ + for(i = 4; i < 46; i++) { + if(!(module_is_set(symbol, symbol->rows - 4, i))) { + set_module(symbol, symbol->rows - 3, i); + } + } + latch = '1'; + for(i = 17; i < 33; i++) { + if(!(module_is_set(symbol, symbol->rows - 4, i))) { + if(latch == '1') { + set_module(symbol, symbol->rows - 3, i); + latch = '0'; + } else { + unset_module(symbol, symbol->rows - 3, i); + latch = '1'; + } + } else { + unset_module(symbol, symbol->rows - 3, i); + latch = '1'; + } + } + symbol->row_height[symbol->rows - 3] = 1; + /* bottom separator */ + for(i = 4; i < 46; i++) { + if(!(module_is_set(symbol, symbol->rows, i))) { + set_module(symbol, symbol->rows - 1, i); + } + } + latch = '1'; + for(i = 16; i < 32; i++) { + if(!(module_is_set(symbol, symbol->rows, i))) { + if(latch == '1') { + set_module(symbol, symbol->rows - 1, i); + latch = '0'; + } else { + unset_module(symbol, symbol->rows - 1, i); + latch = '1'; + } + } else { + unset_module(symbol, symbol->rows - 1, i); + latch = '1'; + } + } + symbol->row_height[symbol->rows - 1] = 1; + if(symbol->width < 50) { symbol->width = 50; } + if(symbol->symbology == BARCODE_RSS14_OMNI_CC) { + /* separator pattern for composite symbol */ + for(i = 4; i < 46; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + latch = '1'; + for(i = 16; i < 32; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + if(latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + } + + + return error_number; +} + +int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ /* GS1 DataBar Limited */ + int error_number = 0, i, mask; + short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; + int left_group, right_group, left_odd, left_even, right_odd, right_even; + int left_character, right_character, left_widths[14], right_widths[14]; + int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count; + char latch, hrt[15], temp[32]; + int separator_row; + + separator_row = 0; + + if(src_len > 13) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, src_len); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + if(src_len == 13) { + if((source[0] != '0') && (source[0] != '1')) { + strcpy(symbol->errtxt, "Input out of range"); + return ERROR_INVALID_DATA; + } + } + + /* make some room for a separator row for composite symbols */ + if(symbol->symbology == BARCODE_RSS_LTD_CC) { + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + } + + for(i = 0; i < 112; i++) { + accum[i] = 0; + x_reg[i] = 0; + y_reg[i] = 0; + } + + binary_load(accum, (char*)source, src_len); + if(symbol->option_1 == 2) { + /* Add symbol linkage flag */ + strcpy(temp, "2015133531096"); + binary_load(y_reg, temp, strlen(temp)); + binary_add(accum, y_reg); + for(i = 0; i < 112; i++) { + y_reg[i] = 0; + } + } + + /* Calculate left and right pair values */ + strcpy(temp, "2013571"); + binary_load(x_reg, temp, strlen(temp)); + + for(i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for(i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if(y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + for(i = 0; i < 112; i++) { + left_reg[i] = y_reg[i]; + right_reg[i] = accum[i]; + } + + left_group = 0; + strcpy(temp, "183063"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 1; } + strcpy(temp, "820063"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 2; } + strcpy(temp, "1000775"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 3; } + strcpy(temp, "1491020"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 4; } + strcpy(temp, "1979844"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 5; } + strcpy(temp, "1996938"); + binary_load(accum, temp, strlen(temp)); + if(islarger(left_reg, accum)) { left_group = 6; } + right_group = 0; + strcpy(temp, "183063"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 1; } + strcpy(temp, "820063"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 2; } + strcpy(temp, "1000775"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 3; } + strcpy(temp, "1491020"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 4; } + strcpy(temp, "1979844"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 5; } + strcpy(temp, "1996938"); + binary_load(accum, temp, strlen(temp)); + if(islarger(right_reg, accum)) { right_group = 6; } + + switch(left_group) { + case 1: strcpy(temp, "183064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 2: strcpy(temp, "820064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 3: strcpy(temp, "1000776"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 4: strcpy(temp, "1491021"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 5: strcpy(temp, "1979845"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 6: strcpy(temp, "1996939"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + } + + switch(right_group) { + case 1: strcpy(temp, "183064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 2: strcpy(temp, "820064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 3: strcpy(temp, "1000776"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 4: strcpy(temp, "1491021"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 5: strcpy(temp, "1979845"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 6: strcpy(temp, "1996939"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + } + + left_character = 0; + right_character = 0; + mask = 0x800000; + for(i = 23; i >= 0; i--) { + if(left_reg[i] == 1) { + left_character += mask; + } + if(right_reg[i] == 1) { + right_character += mask; + } + mask = mask >> 1; + } + + left_odd = left_character / t_even_ltd[left_group]; + left_even = left_character % t_even_ltd[left_group]; + right_odd = right_character / t_even_ltd[right_group]; + right_even = right_character % t_even_ltd[right_group]; + + getRSSwidths(left_odd, modules_odd_ltd[left_group], 7, widest_odd_ltd[left_group], 1); + left_widths[0] = widths[0]; + left_widths[2] = widths[1]; + left_widths[4] = widths[2]; + left_widths[6] = widths[3]; + left_widths[8] = widths[4]; + left_widths[10] = widths[5]; + left_widths[12] = widths[6]; + getRSSwidths(left_even, modules_even_ltd[left_group], 7, widest_even_ltd[left_group], 0); + left_widths[1] = widths[0]; + left_widths[3] = widths[1]; + left_widths[5] = widths[2]; + left_widths[7] = widths[3]; + left_widths[9] = widths[4]; + left_widths[11] = widths[5]; + left_widths[13] = widths[6]; + getRSSwidths(right_odd, modules_odd_ltd[right_group], 7, widest_odd_ltd[right_group], 1); + right_widths[0] = widths[0]; + right_widths[2] = widths[1]; + right_widths[4] = widths[2]; + right_widths[6] = widths[3]; + right_widths[8] = widths[4]; + right_widths[10] = widths[5]; + right_widths[12] = widths[6]; + getRSSwidths(right_even, modules_even_ltd[right_group], 7, widest_even_ltd[right_group], 0); + right_widths[1] = widths[0]; + right_widths[3] = widths[1]; + right_widths[5] = widths[2]; + right_widths[7] = widths[3]; + right_widths[9] = widths[4]; + right_widths[11] = widths[5]; + right_widths[13] = widths[6]; + + checksum = 0; + /* Calculate the checksum */ + for(i = 0; i < 14; i++) { + checksum += checksum_weight_ltd[i] * left_widths[i]; + checksum += checksum_weight_ltd[i + 14] * right_widths[i]; + } + checksum %= 89; + + for(i = 0; i < 14; i++) { + check_elements[i] = finder_pattern_ltd[i + (checksum * 14)]; + } + + total_widths[0] = 1; + total_widths[1] = 1; + total_widths[44] = 1; + total_widths[45] = 1; + for(i = 0; i < 14; i++) { + total_widths[i + 2] = left_widths[i]; + total_widths[i + 16] = check_elements[i]; + total_widths[i + 30] = right_widths[i]; + } + + writer = 0; + latch = '0'; + for(i = 0; i < 46; i++) { + for(j = 0; j < total_widths[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if(symbol->width < writer) { symbol->width = writer; } + symbol->rows = symbol->rows + 1; + + /* add separator pattern if composite symbol */ + if(symbol->symbology == BARCODE_RSS_LTD_CC) { + for(i = 4; i < 70; i++) { + if(!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + } + + /* Calculate check digit from Annex A and place human readable text */ + + check_digit = 0; + count = 0; + + ustrcpy(symbol->text, (unsigned char*)"(01)"); + for(i = 0; i < 14; i++) { + hrt[i] = '0'; + } + for(i = 0; i < src_len; i++) { + hrt[12 - i] = source[src_len - i - 1]; + } + + for (i = 0; i < 13; i++) + { + count += ctoi(hrt[i]); + + if ((i%2) == 0) + { + count += 2 * (ctoi(hrt[i])); + } + } + + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + + hrt[13] = itoc(check_digit); + hrt[14] = '\0'; + + uconcat(symbol->text, (unsigned char*)hrt); + + return error_number; +} + +int general_rules(char field[], char type[]) +{ /* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3 + of ISO/IEC 24724:2006 */ + int block[2][200], block_count, i, j, k; + char current, next, last; + + block_count = 0; + + block[0][block_count] = 1; + block[1][block_count] = type[0]; + + for(i = 1; i < strlen(type); i++) { + current = type[i]; + last = type[i - 1]; + + if(current == last) { + block[0][block_count] = block[0][block_count] + 1; + } else { + block_count++; + block[0][block_count] = 1; + block[1][block_count] = type[i]; + } + } + + block_count++; + + for(i = 0; i < block_count; i++) { + } + + for(i = 0; i < block_count; i++) { + current = block[1][i]; + next = (block[1][i + 1] & 0xFF); + + if((current == ISOIEC) && (i != (block_count - 1))) { + if((next == ANY_ENC) && (block[0][i + 1] >= 4)) { + block[1][i + 1] = NUMERIC; + } + if((next == ANY_ENC) && (block[0][i + 1] < 4)) { + block[1][i + 1] = ISOIEC; + } + if((next == ALPHA_OR_ISO) && (block[0][i + 1] >= 5)) { + block[1][i + 1] = ALPHA; + } + if((next == ALPHA_OR_ISO) && (block[0][i + 1] < 5)) { + block[1][i + 1] = ISOIEC; + } + } + + if(current == ALPHA_OR_ISO) { + block[1][i] = ALPHA; + } + + if((current == ALPHA) && (i != (block_count - 1))) { + if((next == ANY_ENC) && (block[0][i + 1] >= 6)) { + block[1][i + 1] = NUMERIC; + } + if((next == ANY_ENC) && (block[0][i + 1] < 6)) { + if((i == block_count - 2) && (block[0][i + 1] >= 4)) { + block[1][i + 1] = NUMERIC; + } else { + block[1][i + 1] = ALPHA; + } + } + } + + if(current == ANY_ENC) { + block[1][i] = NUMERIC; + } + } + + if(block_count > 1) { + i = 1; + while(i < block_count) { + if(block[1][i - 1] == block[1][i]) { + /* bring together */ + block[0][i - 1] = block[0][i - 1] + block[0][i]; + j = i + 1; + + /* decreace the list */ + while(j < block_count) { + block[0][j - 1] = block[0][j]; + block[1][j - 1] = block[1][j]; + j++; + } + block_count--; + i--; + } + i++; + } + } + + for(i = 0; i < block_count - 1; i++) { + if((block[1][i] == NUMERIC) && (block[0][i] % 2 == 1)) { + /* Odd size numeric block */ + block[0][i] = block[0][i] - 1; + block[0][i + 1] = block[0][i + 1] + 1; + } + } + + j = 0; + for(i = 0; i < block_count; i++) { + for(k = 0; k < block[0][i]; k++) { + type[j] = block[1][i]; + j++; + } + } + + if((block[1][block_count - 1] == NUMERIC) && (block[0][block_count - 1] % 2 == 1)) { + /* If the last block is numeric and an odd size, further + processing needs to be done outside this procedure */ + return 1; + } else { + return 0; + } +} + +int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) +{ /* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */ + int encoding_method, i, mask, j, read_posn, latch, debug = 0, last_mode = ISOIEC; +#ifndef _MSC_VER + char general_field[strlen(source)], general_field_type[strlen(source)]; +#else + char* general_field = (char*)_alloca(strlen(source)); + char* general_field_type = (char*)_alloca(strlen(source)); +#endif + int remainder, d1, d2, value; + char padstring[40]; + + read_posn=0; + value=0; + + /* Decide whether a compressed data field is required and if so what + method to use - method 2 = no compressed data field */ + + if((strlen(source) >= 16) && ((source[0] == '0') && (source[1] == '1'))) { + /* (01) and other AIs */ + encoding_method = 1; + if(debug) printf("Choosing Method 1\n"); + } else { + /* any AIs */ + encoding_method = 2; + if(debug) printf("Choosing Mehod 2\n"); + } + + if(((strlen(source) >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { + /* Possibly encoding method > 2 */ + if(debug) printf("Checking for other methods\n"); + + if((strlen(source) >= 26) && (source[17] == '1')) { + /* Methods 3, 7, 9, 11 and 13 */ + + if(source[18] == '0') { + /* (01) and (310x) */ + char weight_str[7]; + float weight; /* In kilos */ + + for(i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + + if (weight_str[0] == '0') { /* Maximum weight = 99999 */ + + + encoding_method = 7; + + if((source[19] == '3') && (strlen(source) == 26)) { + /* (01) and (3103) */ + weight = atof(weight_str) / 1000.0; + + if(weight <= 32.767) { encoding_method = 3; } + } + + if(strlen(source) == 34){ + if((source[26] == '1') && (source[27] == '1')) { + /* (01), (310x) and (11) - metric weight and production date */ + encoding_method = 7; + } + + if((source[26] == '1') && (source[27] == '3')) { + /* (01), (310x) and (13) - metric weight and packaging date */ + encoding_method = 9; + } + + if((source[26] == '1') && (source[27] == '5')) { + /* (01), (310x) and (15) - metric weight and "best before" date */ + encoding_method = 11; + } + + if((source[26] == '1') && (source[27] == '7')) { + /* (01), (310x) and (17) - metric weight and expiration date */ + encoding_method = 13; + } + } + } + } + if(debug) printf("Now using method %d\n", encoding_method); + } + + if((strlen(source) >= 26) && (source[17] == '2')) { + /* Methods 4, 8, 10, 12 and 14 */ + + if(source[18] == '0') { + /* (01) and (320x) */ + char weight_str[7]; + float weight; /* In pounds */ + + for(i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + + if (weight_str[0] == '0') { /* Maximum weight = 99999 */ + + encoding_method = 8; + + if(((source[19] == '2') || (source[19] == '3')) && (strlen(source) == 26)) { + /* (01) and (3202)/(3203) */ + + if(source[19] == '3') { + weight = atof(weight_str) / 1000.0; + if(weight <= 22.767) { + encoding_method = 4; + } + } else { + weight = atof(weight_str) / 100.0; + if(weight <= 99.99) { + encoding_method = 4; + } + } + + } + + if(strlen(source) == 34){ + if((source[26] == '1') && (source[27] == '1')) { + /* (01), (320x) and (11) - English weight and production date */ + encoding_method = 8; + } + + if((source[26] == '1') && (source[27] == '3')) { + /* (01), (320x) and (13) - English weight and packaging date */ + encoding_method = 10; + } + + if((source[26] == '1') && (source[27] == '5')) { + /* (01), (320x) and (15) - English weight and "best before" date */ + encoding_method = 12; + } + + if((source[26] == '1') && (source[27] == '7')) { + /* (01), (320x) and (17) - English weight and expiration date */ + encoding_method = 14; + } + } + } + } + if(debug) printf("Now using method %d\n", encoding_method); + + } + + if(source[17] == '9') { + /* Methods 5 and 6 */ + if((source[18] == '2') && ((source[19] >= '0') && (source[19] <= '3'))) { + /* (01) and (392x) */ + encoding_method = 5; + } + if((source[18] == '3') && ((source[19] >= '0') && (source[19] <= '3'))) { + /* (01) and (393x) */ + encoding_method = 6; + } + if(debug) printf("Now using method %d\n", encoding_method); + } + } + + switch(encoding_method) { /* Encoding method - Table 10 */ + case 1: concat(binary_string, "1XX"); read_posn = 16; break; + case 2: concat(binary_string, "00XX"); read_posn = 0; break; + case 3: concat(binary_string, "0100"); read_posn = strlen(source); break; + case 4: concat(binary_string, "0101"); read_posn = strlen(source); break; + case 5: concat(binary_string, "01100XX"); read_posn = 20; break; + case 6: concat(binary_string, "01101XX"); read_posn = 23; break; + case 7: concat(binary_string, "0111000"); read_posn = strlen(source); break; + case 8: concat(binary_string, "0111001"); read_posn = strlen(source); break; + case 9: concat(binary_string, "0111010"); read_posn = strlen(source); break; + case 10: concat(binary_string, "0111011"); read_posn = strlen(source); break; + case 11: concat(binary_string, "0111100"); read_posn = strlen(source); break; + case 12: concat(binary_string, "0111101"); read_posn = strlen(source); break; + case 13: concat(binary_string, "0111110"); read_posn = strlen(source); break; + case 14: concat(binary_string, "0111111"); read_posn = strlen(source); break; + } + if(debug) printf("Setting binary = %s\n", binary_string); + + /* Variable length symbol bit field is just given a place holder (XX) + for the time being */ + + /* Verify that the data to be placed in the compressed data field is all + numeric data before carrying out compression */ + for(i = 0; i < read_posn; i++) { + if((source[i] < '0') || (source[i] > '9')) { + if((source[i] != '[') && (source[i] != ']')) { + /* Something is wrong */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + } + } + + /* Now encode the compressed data field */ + + if(debug) printf("Proceeding to encode data\n"); + if(encoding_method == 1) { + /* Encoding method field "1" - general item identification data */ + char group[4]; + int group_val; + + group[0] = source[2]; + group[1] = '\0'; + group_val = atoi(group); + + mask = 0x08; + for(j = 0; j < 4; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + + } + + + if(encoding_method == 3) { + /* Encoding method field "0100" - variable weight item + (0,001 kilogram icrements) */ + char group[4]; + int group_val; + char weight_str[7]; + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + for(i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + group_val = atoi(weight_str); + + mask = 0x4000; + for(j = 0; j < 15; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + + } + + if(encoding_method == 4) { + /* Encoding method field "0101" - variable weight item (0,01 or + 0,001 pound increment) */ + char group[4]; + int group_val; + char weight_str[7]; + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + for(i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + group_val = atoi(weight_str); + + if(source[19] == '3') { + group_val = group_val + 10000; + } + + mask = 0x4000; + for(j = 0; j < 15; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + } + + + if((encoding_method >= 7) && (encoding_method <= 14)) { + /* Encoding method fields "0111000" through "0111111" - variable + weight item plus date */ + char group[4]; + int group_val; + char weight_str[8]; + char date_str[4]; + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + weight_str[0] = source[19]; + + for(i = 0; i < 5; i++) { + weight_str[i + 1] = source[21 + i]; + } + weight_str[6] = '\0'; + group_val = atoi(weight_str); + + mask = 0x80000; + for(j = 0; j < 20; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + if(strlen(source) == 34) { + /* Date information is included */ + date_str[0] = source[28]; + date_str[1] = source[29]; + date_str[2] = '\0'; + group_val = atoi(date_str) * 384; + + date_str[0] = source[30]; + date_str[1] = source[31]; + group_val += (atoi(date_str) - 1) * 32; + + date_str[0] = source[32]; + date_str[1] = source[33]; + group_val += atoi(date_str); + } else { + group_val = 38400; + } + + mask = 0x8000; + for(j = 0; j < 16; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + } + + if(encoding_method == 5) { + /* Encoding method field "01100" - variable measure item and price */ + char group[4]; + int group_val; + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + switch(source[19]) { + case '0': concat(binary_string, "00"); break; + case '1': concat(binary_string, "01"); break; + case '2': concat(binary_string, "10"); break; + case '3': concat(binary_string, "11"); break; + } + } + + if(encoding_method == 6) { + /* Encoding method "01101" - variable measure item and price with ISO 4217 + Currency Code */ + + char group[4]; + int group_val; + char currency_str[5]; + + for(i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + group_val = atoi(group); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + switch(source[19]) { + case '0': concat(binary_string, "00"); break; + case '1': concat(binary_string, "01"); break; + case '2': concat(binary_string, "10"); break; + case '3': concat(binary_string, "11"); break; + } + + for(i = 0; i < 3; i++) { + currency_str[i] = source[20 + i]; + } + currency_str[3] = '\0'; + group_val = atoi(currency_str); + + mask = 0x200; + for(j = 0; j < 10; j++) { + if((group_val & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + + + } + + /* The compressed data field has been processed if appropriate - the + rest of the data (if any) goes into a general-purpose data compaction field */ + + j = 0; + for(i = read_posn; i < strlen(source); i++) { + general_field[j] = source[i]; + j++; + } + general_field[j] = '\0'; + if(debug) printf("General field data = %s\n", general_field); + + latch = 0; + for(i = 0; i < strlen(general_field); i++) { + /* Table 13 - ISO/IEC 646 encodation */ + if((general_field[i] < ' ') || (general_field[i] > 'z')) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } else { + general_field_type[i] = ISOIEC; + } + + if(general_field[i] == '#') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '$') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '@') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == 92) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == '^') { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + if(general_field[i] == 96) { + general_field_type[i] = INVALID_CHAR; latch = 1; + } + + /* Table 12 - Alphanumeric encodation */ + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '*') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == ',') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '-') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '.') { + general_field_type[i] = ALPHA_OR_ISO; + } + if(general_field[i] == '/') { + general_field_type[i] = ALPHA_OR_ISO; + } + + /* Numeric encodation */ + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + general_field_type[i] = ANY_ENC; + } + if(general_field[i] == '[') { + /* FNC1 can be encoded in any system */ + general_field_type[i] = ANY_ENC; + } + + } + + general_field_type[strlen(general_field)] = '\0'; + if(debug) printf("General field type: %s\n", general_field_type); + + if(latch == 1) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + + for(i = 0; i < strlen(general_field); i++) { + if((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ISOIEC; + } + } + + for(i = 0; i < strlen(general_field); i++) { + if((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ALPHA_OR_ISO; + } + } + + latch = general_rules(general_field, general_field_type); + if(debug) printf("General field type: %s\n", general_field_type); + + last_mode = NUMERIC; + + /* Set initial mode if not NUMERIC */ + if(general_field_type[0] == ALPHA) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + last_mode = ALPHA; + } + if(general_field_type[0] == ISOIEC) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + last_mode = ISOIEC; + } + + i = 0; + do { + if(debug) printf("Processing character %d ", i); + switch(general_field_type[i]) { + case NUMERIC: + if(debug) printf("as NUMERIC:"); + + if(last_mode != NUMERIC) { + concat(binary_string, "000"); /* Numeric latch */ + if(debug) printf("\n"); + } + + if(debug) printf(" %c%c > ", general_field[i], general_field[i + 1]); + if(general_field[i] != '[') { + d1 = ctoi(general_field[i]); + } else { + d1 = 10; + } + + if(general_field[i + 1] != '[') { + d2 = ctoi(general_field[i + 1]); + } else { + d2 = 10; + } + + value = (11 * d1) + d2 + 8; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + if(debug) printf("0"); + } else { + concat(binary_string, "1"); + if(debug) printf("1"); + } + mask = mask >> 1; + } + + i += 2; + if(debug) printf("\n"); + last_mode = NUMERIC; + break; + + case ALPHA: + if(debug) printf("as ALPHA\n"); + if(i != 0) { + if(last_mode == NUMERIC) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + } + if(last_mode == ISOIEC) { + concat(binary_string, "00100"); /* Alphanumeric latch */ + } + } + + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + + value = general_field[i] - 43; + + mask = 0x10; + for(j = 0; j < 5; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + + value = general_field[i] - 33; + + mask = 0x20; + for(j = 0; j < 6; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + last_mode = ALPHA; + if(general_field[i] == '[') { concat(binary_string, "01111"); last_mode = NUMERIC; } /* FNC1/Numeric latch */ + if(general_field[i] == '*') concat(binary_string, "111010"); /* asterisk */ + if(general_field[i] == ',') concat(binary_string, "111011"); /* comma */ + if(general_field[i] == '-') concat(binary_string, "111100"); /* minus or hyphen */ + if(general_field[i] == '.') concat(binary_string, "111101"); /* period or full stop */ + if(general_field[i] == '/') concat(binary_string, "111110"); /* slash or solidus */ + + i++; + break; + + case ISOIEC: + if(debug) printf("as ISOIEC\n"); + if(i != 0) { + if(last_mode == NUMERIC) { + concat(binary_string, "0000"); /* Alphanumeric latch */ + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } + if(last_mode == ALPHA) { + concat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } + } + + if((general_field[i] >= '0') && (general_field[i] <= '9')) { + + value = general_field[i] - 43; + + mask = 0x10; + for(j = 0; j < 5; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + + value = general_field[i] - 1; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + if((general_field[i] >= 'a') && (general_field[i] <= 'z')) { + + value = general_field[i] - 7; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + last_mode = ISOIEC; + if(general_field[i] == '[') { concat(binary_string, "01111"); last_mode = NUMERIC; } /* FNC1/Numeric latch */ + if(general_field[i] == '!') concat(binary_string, "11101000"); /* exclamation mark */ + if(general_field[i] == 34) concat(binary_string, "11101001"); /* quotation mark */ + if(general_field[i] == 37) concat(binary_string, "11101010"); /* percent sign */ + if(general_field[i] == '&') concat(binary_string, "11101011"); /* ampersand */ + if(general_field[i] == 39) concat(binary_string, "11101100"); /* apostrophe */ + if(general_field[i] == '(') concat(binary_string, "11101101"); /* left parenthesis */ + if(general_field[i] == ')') concat(binary_string, "11101110"); /* right parenthesis */ + if(general_field[i] == '*') concat(binary_string, "11101111"); /* asterisk */ + if(general_field[i] == '+') concat(binary_string, "11110000"); /* plus sign */ + if(general_field[i] == ',') concat(binary_string, "11110001"); /* comma */ + if(general_field[i] == '-') concat(binary_string, "11110010"); /* minus or hyphen */ + if(general_field[i] == '.') concat(binary_string, "11110011"); /* period or full stop */ + if(general_field[i] == '/') concat(binary_string, "11110100"); /* slash or solidus */ + if(general_field[i] == ':') concat(binary_string, "11110101"); /* colon */ + if(general_field[i] == ';') concat(binary_string, "11110110"); /* semicolon */ + if(general_field[i] == '<') concat(binary_string, "11110111"); /* less-than sign */ + if(general_field[i] == '=') concat(binary_string, "11111000"); /* equals sign */ + if(general_field[i] == '>') concat(binary_string, "11111001"); /* greater-than sign */ + if(general_field[i] == '?') concat(binary_string, "11111010"); /* question mark */ + if(general_field[i] == '_') concat(binary_string, "11111011"); /* underline or low line */ + if(general_field[i] == ' ') concat(binary_string, "11111100"); /* space */ + + i++; + break; + } + } while (i + latch < strlen(general_field)); + if(debug) printf("Resultant binary = %s\n", binary_string); + if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); + + remainder = 12 - (strlen(binary_string) % 12); + if(remainder == 12) { remainder = 0; } + if(strlen(binary_string) < 36) { remainder = 36 - strlen(binary_string); } + + if(latch == 1) { + /* There is still one more numeric digit to encode */ + if(debug) printf("Adding extra (odd) numeric digit\n"); + + if(last_mode == NUMERIC) { + if((remainder >= 4) && (remainder <= 6)) { + value = ctoi(general_field[i]); + value++; + + mask = 0x08; + for(j = 0; j < 4; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } else { + d1 = ctoi(general_field[i]); + d2 = 10; + + value = (11 * d1) + d2 + 8; + + mask = 0x40; + for(j = 0; j < 7; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + } else { + value = general_field[i] - 43; + + mask = 0x10; + for(j = 0; j < 5; j++) { + if((value & mask) == 0x00) { + concat(binary_string, "0"); + } else { + concat(binary_string, "1"); + } + mask = mask >> 1; + } + } + + remainder = 12 - (strlen(binary_string) % 12); + if(remainder == 12) { remainder = 0; } + if(strlen(binary_string) < 36) { remainder = 36 - strlen(binary_string); } + if(debug) printf("Resultant binary = %s\n", binary_string); + if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); + } + + if(strlen(binary_string) > 252) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + + /* Now add padding to binary string (7.2.5.5.4) */ + i = remainder; + if((strlen(general_field) != 0) && (last_mode == NUMERIC)) { + strcpy(padstring, "0000"); + i -= 4; + } else { + strcpy(padstring, ""); + } + for(;i > 0;i -= 5) { + concat(padstring, "00100"); + } + + padstring[remainder] = '\0'; + concat(binary_string, padstring); + + /* Patch variable length symbol bit field */ + d1 = ((strlen(binary_string) / 12) + 1) % 2; + if(strlen(binary_string) <= 156) { d2 = 0; } else { d2 = 1; } + + if(encoding_method == 1) { + if(d1 == 0) { binary_string[2] = '0'; } else { binary_string[2] = '1'; } + if(d2 == 0) { binary_string[3] = '0'; } else { binary_string[3] = '1'; } + } + if(encoding_method == 2) { + if(d1 == 0) { binary_string[3] = '0'; } else { binary_string[3] = '1'; } + if(d2 == 0) { binary_string[4] = '0'; } else { binary_string[4] = '1'; } + } + if((encoding_method == 5) || (encoding_method == 6)) { + if(d1 == 0) { binary_string[6] = '0'; } else { binary_string[6] = '1'; } + if(d2 == 0) { binary_string[7] = '0'; } else { binary_string[7] = '1'; } + } + if(debug) printf("Resultant binary = %s\n", binary_string); + if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); + return 0; +} + +int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ /* GS1 DataBar Expanded */ + int i, j, k, l, data_chars, vs[21], group[21], v_odd[21], v_even[21]; + char substring[21][14], latch; + int char_widths[21][8], checksum, check_widths[8], c_group; + int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer; + int row, elements_in_sub, special_case_row, left_to_right; + int codeblocks, sub_elements[235], stack_rows, current_row, current_block; + int separator_row; +#ifndef _MSC_VER + char reduced[src_len], binary_string[7 * src_len]; +#else + char* reduced = (char*)_alloca(src_len); + char* binary_string = (char*)_alloca(7 * src_len); +#endif + + separator_row = 0; + reader=0; + + if(symbol->input_mode != GS1_MODE) { + /* GS1 data has not been verified yet */ + i = gs1_verify(symbol, source, src_len, reduced); + if(i != 0) { return i; } + } + + if((symbol->symbology == BARCODE_RSS_EXP_CC) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) { + /* make space for a composite separator pattern */ + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + } + + strcpy(binary_string, ""); + + if(symbol->option_1 == 2) { + concat(binary_string, "1"); + } else { + concat(binary_string, "0"); + } + + i = rss_binary_string(symbol, reduced, binary_string); + if(i != 0) { + return i; + } + + data_chars = strlen(binary_string) / 12; + + for(i = 0; i < data_chars; i++) { + for(j = 0; j < 12; j++) { + substring[i][j] = binary_string[(i * 12) + j]; + } + substring[i][12] = '\0'; + } + + for(i = 0; i < data_chars; i++) { + vs[i] = 0; + if(substring[i][0] == '1') { vs[i] += 2048; } + if(substring[i][1] == '1') { vs[i] += 1024; } + if(substring[i][2] == '1') { vs[i] += 512; } + if(substring[i][3] == '1') { vs[i] += 256; } + if(substring[i][4] == '1') { vs[i] += 128; } + if(substring[i][5] == '1') { vs[i] += 64; } + if(substring[i][6] == '1') { vs[i] += 32; } + if(substring[i][7] == '1') { vs[i] += 16; } + if(substring[i][8] == '1') { vs[i] += 8; } + if(substring[i][9] == '1') { vs[i] += 4; } + if(substring[i][10] == '1') { vs[i] += 2; } + if(substring[i][11] == '1') { vs[i] += 1; } + } + + for(i = 0; i < data_chars; i++) { + if(vs[i] <= 347) { group[i] = 1; } + if((vs[i] >= 348) && (vs[i] <= 1387)) { group[i] = 2; } + if((vs[i] >= 1388) && (vs[i] <= 2947)) { group[i] = 3; } + if((vs[i] >= 2948) && (vs[i] <= 3987)) { group[i] = 4; } + if(vs[i] >= 3988) { group[i] = 5; } + v_odd[i] = (vs[i] - g_sum_exp[group[i] - 1]) / t_even_exp[group[i] - 1]; + v_even[i] = (vs[i] - g_sum_exp[group[i] - 1]) % t_even_exp[group[i] - 1]; + + getRSSwidths(v_odd[i], modules_odd_exp[group[i] - 1], 4, widest_odd_exp[group[i] - 1], 0); + char_widths[i][0] = widths[0]; + char_widths[i][2] = widths[1]; + char_widths[i][4] = widths[2]; + char_widths[i][6] = widths[3]; + getRSSwidths(v_even[i], modules_even_exp[group[i] - 1], 4, widest_even_exp[group[i] - 1], 1); + char_widths[i][1] = widths[0]; + char_widths[i][3] = widths[1]; + char_widths[i][5] = widths[2]; + char_widths[i][7] = widths[3]; + } + + /* 7.2.6 Check character */ + /* The checksum value is equal to the mod 211 residue of the weighted sum of the widths of the + elements in the data characters. */ + checksum = 0; + for(i = 0; i < data_chars; i++) { + row = weight_rows[(((data_chars - 2) / 2) * 21) + i]; + for(j = 0; j < 8; j++) { + checksum += (char_widths[i][j] * checksum_weight_exp[(row * 8) + j]); + + } + } + + check_char = (211 * ((data_chars + 1) - 4)) + (checksum % 211); + + if(check_char <= 347) { c_group = 1; } + if((check_char >= 348) && (check_char <= 1387)) { c_group = 2; } + if((check_char >= 1388) && (check_char <= 2947)) { c_group = 3; } + if((check_char >= 2948) && (check_char <= 3987)) { c_group = 4; } + if(check_char >= 3988) { c_group = 5; } + + c_odd = (check_char - g_sum_exp[c_group - 1]) / t_even_exp[c_group - 1]; + c_even = (check_char - g_sum_exp[c_group - 1]) % t_even_exp[c_group - 1]; + + getRSSwidths(c_odd, modules_odd_exp[c_group - 1], 4, widest_odd_exp[c_group - 1], 0); + check_widths[0] = widths[0]; + check_widths[2] = widths[1]; + check_widths[4] = widths[2]; + check_widths[6] = widths[3]; + getRSSwidths(c_even, modules_even_exp[c_group - 1], 4, widest_even_exp[c_group - 1], 1); + check_widths[1] = widths[0]; + check_widths[3] = widths[1]; + check_widths[5] = widths[2]; + check_widths[7] = widths[3]; + + /* Initialise element array */ + pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) % 2)) * 5) + ((data_chars + 1) * 8) + 4; + for(i = 0; i < pattern_width; i++) { + elements[i] = 0; + } + + elements[0] = 1; + elements[1] = 1; + elements[pattern_width - 2] = 1; + elements[pattern_width - 1] = 1; + + /* Put finder patterns in element array */ + for(i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) % 2)); i++) { + k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) % 2)) - 1) * 11) + i; + for(j = 0; j < 5; j++) { + elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j]; + } + } + + /* Put check character in element array */ + for(i = 0; i < 8; i++) { + elements[i + 2] = check_widths[i]; + } + + /* Put forward reading data characters in element array */ + for(i = 1; i < data_chars; i += 2) { + for(j = 0; j < 8; j++) { + elements[(((i - 1) / 2) * 21) + 23 + j] = char_widths[i][j]; + } + } + + /* Put reversed data characters in element array */ + for(i = 0; i < data_chars; i += 2) { + for(j = 0; j < 8; j++) { + elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j]; + } + } + + if((symbol->symbology == BARCODE_RSS_EXP) || (symbol->symbology == BARCODE_RSS_EXP_CC)) { + /* Copy elements into symbol */ + writer = 0; + latch = '0'; + for(i = 0; i < pattern_width; i++) { + for(j = 0; j < elements[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if(symbol->width < writer) { symbol->width = writer; } + symbol->rows = symbol->rows + 1; + if(symbol->symbology == BARCODE_RSS_EXP_CC) { + for(j = 4; j < (symbol->width - 4); j++) { + if(module_is_set(symbol, separator_row + 1, j)) { + unset_module(symbol, separator_row, j); + } else { + set_module(symbol, separator_row, j); + } + } + /* finder bar adjustment */ + for(j = 0; j < (writer / 49); j++) { + k = (49 * j) + 18; + for(i = 0; i < 15; i++) { + if((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && + (!(module_is_set(symbol, separator_row + 1, i + k))) && + module_is_set(symbol, separator_row, i + k - 1)) { + unset_module(symbol, separator_row, i + k); + } + } + } + } + + /* Add human readable text */ + for(i = 0; i <= src_len; i++) { + if((source[i] != '[') && (source[i] != ']')) { + symbol->text[i] = source[i]; + } else { + if(source[i] == '[') { + symbol->text[i] = '('; + } + if(source[i] == ']') { + symbol->text[i] = ')'; + } + } + } + + } else { + /* RSS Expanded Stacked */ + + codeblocks = (data_chars + 1) / 2; + + if((symbol->option_2 < 1) || (symbol->option_2 > 10)) { + symbol->option_2 = 2; + } + if((symbol->option_1 == 2) && (symbol->option_2 == 1)) { + /* "There shall be a minimum of four symbol characters in the + first row of an RSS Expanded Stacked symbol when it is the linear + component of an EAN.UCC Composite symbol." */ + symbol->option_2 = 2; + } + + stack_rows = codeblocks / symbol->option_2; + if(codeblocks % symbol->option_2 > 0) { + stack_rows++; + } + + current_block = 0; + for(current_row = 1; current_row <= stack_rows; current_row++) { + for(i = 0; i < 235; i++) { + sub_elements[i] = 0; + } + special_case_row = 0; + + /* Row Start */ + sub_elements[0] = 1; + sub_elements[1] = 1; + elements_in_sub = 2; + + /* Row Data */ + reader = 0; + do { + if(((symbol->option_2 % 2 == 1) || (current_row % 2 == 1)) || + ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && + ((((current_row * symbol->option_2) - codeblocks) % 2) == 1) )) { + /* left to right */ + left_to_right = 1; + i = 2 + (current_block * 21); + for(j = 0; j < 21; j++) { + sub_elements[j + (reader * 21) + 2] = elements[i + j]; + elements_in_sub++; + } + } else { + /* right to left */ + left_to_right = 0; + if((current_row * symbol->option_2) < codeblocks) { + /* a full row */ + i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21); + for(j = 0; j < 21; j++) { + sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j]; + elements_in_sub++; + } + } else { + /* a partial row */ + k = ((current_row * symbol->option_2) - codeblocks); + l = (current_row * symbol->option_2) - reader - 1; + i = 2 + ((l - k) * 21); + for(j = 0; j < 21; j++) { + sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j]; + elements_in_sub++; + } + } + } + reader++; + current_block++; + } while ((reader < symbol->option_2) && (current_block < codeblocks)); + + /* Row Stop */ + sub_elements[elements_in_sub] = 1; + sub_elements[elements_in_sub + 1] = 1; + elements_in_sub += 2; + + if(current_row % 2 == 1) { + latch = '0'; + } else { + latch = '1'; + } + + if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && + ((((current_row * symbol->option_2) - codeblocks) % 2) == 1) ) { + /* Special case bottom row */ + special_case_row = 1; + sub_elements[0] = 2; + latch = '0'; + } + + writer = 0; + for(i = 0; i < elements_in_sub; i++) { + for(j = 0; j < sub_elements[i]; j++) { + if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } + writer++; + } + if(latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if(symbol->width < writer) { symbol->width = writer; } + + if(current_row != 1) { + /* middle separator pattern (above current row) */ + for(j = 5; j < (49 * symbol->option_2); j += 2) { + set_module(symbol, symbol->rows - 2, j); + } + symbol->row_height[symbol->rows - 2] = 1; + /* bottom separator pattern (above current row) */ + for(j = 4; j < (writer - 4); j++) { + if(module_is_set(symbol, symbol->rows, j)) { + unset_module(symbol, symbol->rows - 1, j); + } else { + set_module(symbol, symbol->rows - 1, j); + } + } + symbol->row_height[symbol->rows - 1] = 1; + /* finder bar adjustment */ + for(j = 0; j < reader; j++) { + if(special_case_row == 0) { + k = (49 * j) + 18; + } else { + k = (49 * j) + 19; + } + if(left_to_right) { + for(i = 0; i < 15; i++) { + if((!(module_is_set(symbol, symbol->rows, i + k - 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows - 1, i + k - 1)) { + unset_module(symbol, symbol->rows - 1, i + k); + } + } + } else { + for(i = 14; i >= 0; i--) { + if((!(module_is_set(symbol, symbol->rows, i + k + 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows - 1, i + k + 1)) { + unset_module(symbol, symbol->rows - 1, i + k); + } + } + } + } + } + + if(current_row != stack_rows) { + /* top separator pattern (below current row) */ + for(j = 4; j < (writer - 4); j++) { + if(module_is_set(symbol, symbol->rows, j)) { + unset_module(symbol, symbol->rows + 1, j); + } else { + set_module(symbol, symbol->rows + 1, j); + } + } + symbol->row_height[symbol->rows + 1] = 1; + /* finder bar adjustment */ + for(j = 0; j < reader; j++) { + k = (49 * j) + 18; + if(left_to_right) { + for(i = 0; i < 15; i++) { + if((!(module_is_set(symbol, symbol->rows, i + k - 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows + 1, i + k - 1)) { + unset_module(symbol, symbol->rows + 1, i + k); + } + } + } else{ + for(i = 14; i >= 0; i--) { + if((!(module_is_set(symbol, symbol->rows, i + k + 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows + 1, i + k + 1)) { + unset_module(symbol, symbol->rows + 1, i + k); + } + } + } + } + } + + symbol->rows = symbol->rows + 4; + } + symbol->rows = symbol->rows - 3; + if(symbol->symbology == BARCODE_RSS_EXPSTACK_CC) { + for(j = 4; j < (symbol->width - 4); j++) { + if(module_is_set(symbol, separator_row + 1, j)) { + unset_module(symbol, separator_row, j); + } else { + set_module(symbol, separator_row, j); + } + } + /* finder bar adjustment */ + for(j = 0; j < reader; j++) { + k = (49 * j) + 18; + for(i = 0; i < 15; i++) { + if((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && + (!(module_is_set(symbol, separator_row + 1, i + k))) && + module_is_set(symbol, separator_row, i + k - 1)) { + unset_module(symbol, separator_row, i + k); + } + } + } + } + + } + + return 0; +} diff --git a/backend/rss.h b/backend/rss.h new file mode 100644 index 00000000..f1463a9b --- /dev/null +++ b/backend/rss.h @@ -0,0 +1,225 @@ +/* rss.h - Data tables for Reduced Space Symbology */ + +/* + libzint - the open source barcode library + Copyright (C) 2007 Robin Stuart + + 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. +*/ + +#define NUMERIC 110 +#define ALPHA 97 +#define ISOIEC 105 +#define INVALID_CHAR 100 +#define ANY_ENC 120 +#define ALPHA_OR_ISO 121 + +/* RSS-14 Tables */ +static int g_sum_table[9] = { 0, 161, 961, 2015, 2715, 0, 336, 1036, 1516}; +static int t_table[9] = { 1, 10, 34, 70, 126, 4, 20, 48, 81}; +static int modules_odd[9] = { 12, 10, 8, 6, 4, 5, 7, 9, 11 }; +static int modules_even[9] = { 4, 6, 8, 10, 12, 10, 8, 6, 4 }; +static int widest_odd[9] = { 8, 6, 4, 3, 1, 2, 4, 6, 8 }; +static int widest_even[9] = { 1, 3, 5, 6, 8, 7, 5, 3, 1 }; +static int widths[8]; +static int finder_pattern[45] = { + 3, 8, 2, 1, 1, + 3, 5, 5, 1, 1, + 3, 3, 7, 1, 1, + 3, 1, 9, 1, 1, + 2, 7, 4, 1, 1, + 2, 5, 6, 1, 1, + 2, 3, 8, 1, 1, + 1, 5, 7, 1, 1, + 1, 3, 9, 1, 1 +}; +static int checksum_weight[32] = { /* Table 5 */ + 1, 3, 9, 27, 2, 6, 18, 54, + 4, 12, 36, 29, 8, 24, 72, 58, + 16, 48, 65, 37, 32, 17, 51, 74, + 64, 34, 23, 69, 49, 68, 46, 59 +}; + +/* RSS Limited Tables */ +static int t_even_ltd[7] = { 28, 728, 6454, 203, 2408, 1, 16632 }; +static int modules_odd_ltd[7] = { 17, 13, 9, 15, 11, 19, 7 }; +static int modules_even_ltd[7] = { 9, 13, 17, 11, 15, 7, 19 }; +static int widest_odd_ltd[7] = { 6, 5, 3, 5, 4, 8, 1 }; +static int widest_even_ltd[7] = { 3, 4, 6, 4, 5, 1, 8 }; +static int checksum_weight_ltd[28] = { /* Table 7 */ + 1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66, + 20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74 +}; +static int finder_pattern_ltd[1232] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, + 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1 +}; + +/* RSS Expanded Tables */ +static int g_sum_exp[5] = { 0, 348, 1388, 2948, 3988 }; +static int t_even_exp[5] = { 4, 20, 52, 104, 204 }; +static int modules_odd_exp[5] = { 12, 10, 8, 6, 4 }; +static int modules_even_exp[5] = { 5, 7, 9, 11, 13 }; +static int widest_odd_exp[5] = { 7, 5, 4, 3, 1 }; +static int widest_even_exp[5] = { 2, 4, 5, 6, 8 }; +static int checksum_weight_exp[184] = { /* Table 14 */ + 1, 3, 9, 27, 81, 32, 96, 77, + 20, 60, 180, 118, 143, 7, 21, 63, + 189, 145, 13, 39, 117, 140, 209, 205, + 193, 157, 49, 147, 19, 57, 171, 91, + 62, 186, 136, 197, 169, 85, 44, 132, + 185, 133, 188, 142, 4, 12, 36, 108, + 113, 128, 173, 97, 80, 29, 87, 50, + 150, 28, 84, 41, 123, 158, 52, 156, + 46, 138, 203, 187, 139, 206, 196, 166, + 76, 17, 51, 153, 37, 111, 122, 155, + 43, 129, 176, 106, 107, 110, 119, 146, + 16, 48, 144, 10, 30, 90, 59, 177, + 109, 116, 137, 200, 178, 112, 125, 164, + 70, 210, 208, 202, 184, 130, 179, 115, + 134, 191, 151, 31, 93, 68, 204, 190, + 148, 22, 66, 198, 172, 94, 71, 2, + 6, 18, 54, 162, 64, 192, 154, 40, + 120, 149, 25, 75, 14, 42, 126, 167, + 79, 26, 78, 23, 69, 207, 199, 175, + 103, 98, 83, 38, 114, 131, 182, 124, + 161, 61, 183, 127, 170, 88, 53, 159, + 55, 165, 73, 8, 24, 72, 5, 15, + 45, 135, 194, 160, 58, 174, 100, 89 +}; +static int finder_pattern_exp[60] = { /* Table 15 */ + 1, 8, 4, 1, 1, + 1, 1, 4, 8, 1, + 3, 6, 4, 1, 1, + 1, 1, 4, 6, 3, + 3, 4, 6, 1, 1, + 1, 1, 6, 4, 3, + 3, 2, 8, 1, 1, + 1, 1, 8, 2, 3, + 2, 6, 5, 1, 1, + 1, 1, 5, 6, 2, + 2, 2, 9, 1, 1, + 1, 1, 9, 2, 2 +}; +static int finder_sequence[198] = { /* Table 16 */ + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0, + 1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11 +}; +static int weight_rows[210] = { + 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20 +}; diff --git a/backend/sjis.h b/backend/sjis.h new file mode 100644 index 00000000..a75d80b0 --- /dev/null +++ b/backend/sjis.h @@ -0,0 +1,6875 @@ +/* sjis.h - Unicode to Shift JIS lookup table + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +/* Derived from : +## Shift_JIS (JIS X 0208:1997 Appendix 1) vs Unicode mapping table +## +## Date: 06 Mar 2002 06:01:22 GMT +## License: +## Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved. +## Copyright (C) 2001 I'O, All Rights Reserved. +## You can use, modify, distribute this table freely. +*/ + +unsigned long int sjis_lookup[] = { + 0x005C,0x815F, // REVERSE SOLIDUS + 0x00A2,0x8191, // CENT SIGN + 0x00A3,0x8192, // POUND SIGN + 0x00A7,0x8198, // SECTION SIGN + 0x00A8,0x814E, // DIAERESIS + 0x00AC,0x81CA, // NOT SIGN + 0x00B0,0x818B, // DEGREE SIGN + 0x00B1,0x817D, // PLUS-MINUS SIGN + 0x00B4,0x814C, // ACUTE ACCENT + 0x00B6,0x81F7, // PILCROW SIGN + 0x00D7,0x817E, // MULTIPLICATION SIGN + 0x00F7,0x8180, // DIVISION SIGN + 0x0391,0x839F, // GREEK CAPITAL LETTER ALPHA + 0x0392,0x83A0, // GREEK CAPITAL LETTER BETA + 0x0393,0x83A1, // GREEK CAPITAL LETTER GAMMA + 0x0394,0x83A2, // GREEK CAPITAL LETTER DELTA + 0x0395,0x83A3, // GREEK CAPITAL LETTER EPSILON + 0x0396,0x83A4, // GREEK CAPITAL LETTER ZETA + 0x0397,0x83A5, // GREEK CAPITAL LETTER ETA + 0x0398,0x83A6, // GREEK CAPITAL LETTER THETA + 0x0399,0x83A7, // GREEK CAPITAL LETTER IOTA + 0x039A,0x83A8, // GREEK CAPITAL LETTER KAPPA + 0x039B,0x83A9, // GREEK CAPITAL LETTER LAMDA + 0x039C,0x83AA, // GREEK CAPITAL LETTER MU + 0x039D,0x83AB, // GREEK CAPITAL LETTER NU + 0x039E,0x83AC, // GREEK CAPITAL LETTER XI + 0x039F,0x83AD, // GREEK CAPITAL LETTER OMICRON + 0x03A0,0x83AE, // GREEK CAPITAL LETTER PI + 0x03A1,0x83AF, // GREEK CAPITAL LETTER RHO + 0x03A3,0x83B0, // GREEK CAPITAL LETTER SIGMA + 0x03A4,0x83B1, // GREEK CAPITAL LETTER TAU + 0x03A5,0x83B2, // GREEK CAPITAL LETTER UPSILON + 0x03A6,0x83B3, // GREEK CAPITAL LETTER PHI + 0x03A7,0x83B4, // GREEK CAPITAL LETTER CHI + 0x03A8,0x83B5, // GREEK CAPITAL LETTER PSI + 0x03A9,0x83B6, // GREEK CAPITAL LETTER OMEGA + 0x03B1,0x83BF, // GREEK SMALL LETTER ALPHA + 0x03B2,0x83C0, // GREEK SMALL LETTER BETA + 0x03B3,0x83C1, // GREEK SMALL LETTER GAMMA + 0x03B4,0x83C2, // GREEK SMALL LETTER DELTA + 0x03B5,0x83C3, // GREEK SMALL LETTER EPSILON + 0x03B6,0x83C4, // GREEK SMALL LETTER ZETA + 0x03B7,0x83C5, // GREEK SMALL LETTER ETA + 0x03B8,0x83C6, // GREEK SMALL LETTER THETA + 0x03B9,0x83C7, // GREEK SMALL LETTER IOTA + 0x03BA,0x83C8, // GREEK SMALL LETTER KAPPA + 0x03BB,0x83C9, // GREEK SMALL LETTER LAMDA + 0x03BC,0x83CA, // GREEK SMALL LETTER MU + 0x03BD,0x83CB, // GREEK SMALL LETTER NU + 0x03BE,0x83CC, // GREEK SMALL LETTER XI + 0x03BF,0x83CD, // GREEK SMALL LETTER OMICRON + 0x03C0,0x83CE, // GREEK SMALL LETTER PI + 0x03C1,0x83CF, // GREEK SMALL LETTER RHO + 0x03C3,0x83D0, // GREEK SMALL LETTER SIGMA + 0x03C4,0x83D1, // GREEK SMALL LETTER TAU + 0x03C5,0x83D2, // GREEK SMALL LETTER UPSILON + 0x03C6,0x83D3, // GREEK SMALL LETTER PHI + 0x03C7,0x83D4, // GREEK SMALL LETTER CHI + 0x03C8,0x83D5, // GREEK SMALL LETTER PSI + 0x03C9,0x83D6, // GREEK SMALL LETTER OMEGA + 0x0401,0x8446, // CYRILLIC CAPITAL LETTER IO + 0x0410,0x8440, // CYRILLIC CAPITAL LETTER A + 0x0411,0x8441, // CYRILLIC CAPITAL LETTER BE + 0x0412,0x8442, // CYRILLIC CAPITAL LETTER VE + 0x0413,0x8443, // CYRILLIC CAPITAL LETTER GHE + 0x0414,0x8444, // CYRILLIC CAPITAL LETTER DE + 0x0415,0x8445, // CYRILLIC CAPITAL LETTER IE + 0x0416,0x8447, // CYRILLIC CAPITAL LETTER ZHE + 0x0417,0x8448, // CYRILLIC CAPITAL LETTER ZE + 0x0418,0x8449, // CYRILLIC CAPITAL LETTER I + 0x0419,0x844A, // CYRILLIC CAPITAL LETTER SHORT I + 0x041A,0x844B, // CYRILLIC CAPITAL LETTER KA + 0x041B,0x844C, // CYRILLIC CAPITAL LETTER EL + 0x041C,0x844D, // CYRILLIC CAPITAL LETTER EM + 0x041D,0x844E, // CYRILLIC CAPITAL LETTER EN + 0x041E,0x844F, // CYRILLIC CAPITAL LETTER O + 0x041F,0x8450, // CYRILLIC CAPITAL LETTER PE + 0x0420,0x8451, // CYRILLIC CAPITAL LETTER ER + 0x0421,0x8452, // CYRILLIC CAPITAL LETTER ES + 0x0422,0x8453, // CYRILLIC CAPITAL LETTER TE + 0x0423,0x8454, // CYRILLIC CAPITAL LETTER U + 0x0424,0x8455, // CYRILLIC CAPITAL LETTER EF + 0x0425,0x8456, // CYRILLIC CAPITAL LETTER HA + 0x0426,0x8457, // CYRILLIC CAPITAL LETTER TSE + 0x0427,0x8458, // CYRILLIC CAPITAL LETTER CHE + 0x0428,0x8459, // CYRILLIC CAPITAL LETTER SHA + 0x0429,0x845A, // CYRILLIC CAPITAL LETTER SHCHA + 0x042B,0x845C, // CYRILLIC CAPITAL LETTER YERU + 0x042C,0x845D, // CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042D,0x845E, // CYRILLIC CAPITAL LETTER E + 0x042E,0x845F, // CYRILLIC CAPITAL LETTER YU + 0x042F,0x8460, // CYRILLIC CAPITAL LETTER YA + 0x0430,0x8470, // CYRILLIC SMALL LETTER A + 0x0431,0x8471, // CYRILLIC SMALL LETTER BE + 0x0432,0x8472, // CYRILLIC SMALL LETTER VE + 0x0433,0x8473, // CYRILLIC SMALL LETTER GHE + 0x0434,0x8474, // CYRILLIC SMALL LETTER DE + 0x0435,0x8475, // CYRILLIC SMALL LETTER IE + 0x0436,0x8477, // CYRILLIC SMALL LETTER ZHE + 0x0437,0x8478, // CYRILLIC SMALL LETTER ZE + 0x0438,0x8479, // CYRILLIC SMALL LETTER I + 0x0439,0x847A, // CYRILLIC SMALL LETTER SHORT I + 0x043A,0x847B, // CYRILLIC SMALL LETTER KA + 0x043B,0x847C, // CYRILLIC SMALL LETTER EL + 0x043C,0x847D, // CYRILLIC SMALL LETTER EM + 0x043D,0x847E, // CYRILLIC SMALL LETTER EN + 0x043E,0x8480, // CYRILLIC SMALL LETTER O + 0x043F,0x8481, // CYRILLIC SMALL LETTER PE + 0x0440,0x8482, // CYRILLIC SMALL LETTER ER + 0x0441,0x8483, // CYRILLIC SMALL LETTER ES + 0x0442,0x8484, // CYRILLIC SMALL LETTER TE + 0x0443,0x8485, // CYRILLIC SMALL LETTER U + 0x0444,0x8486, // CYRILLIC SMALL LETTER EF + 0x0445,0x8487, // CYRILLIC SMALL LETTER HA + 0x0446,0x8488, // CYRILLIC SMALL LETTER TSE + 0x0447,0x8489, // CYRILLIC SMALL LETTER CHE + 0x0448,0x848A, // CYRILLIC SMALL LETTER SHA + 0x0449,0x848B, // CYRILLIC SMALL LETTER SHCHA + 0x044A,0x848C, // CYRILLIC SMALL LETTER HARD SIGN + 0x044B,0x848D, // CYRILLIC SMALL LETTER YERU + 0x044C,0x848E, // CYRILLIC SMALL LETTER SOFT SIGN + 0x044D,0x848F, // CYRILLIC SMALL LETTER E + 0x044E,0x8490, // CYRILLIC SMALL LETTER YU + 0x044F,0x8491, // CYRILLIC SMALL LETTER YA + 0x0451,0x8476, // CYRILLIC SMALL LETTER IO + 0x2010,0x815D, // HYPHEN + 0x2014,0x815C, // EM DASH + 0x2016,0x8161, // DOUBLE VERTICAL LINE + 0x2018,0x8165, // LEFT SINGLE QUOTATION MARK + 0x2019,0x8166, // RIGHT SINGLE QUOTATION MARK + 0x201C,0x8167, // LEFT DOUBLE QUOTATION MARK + 0x201D,0x8168, // RIGHT DOUBLE QUOTATION MARK + 0x2020,0x81F5, // DAGGER + 0x2021,0x81F6, // DOUBLE DAGGER + 0x2025,0x8164, // TWO DOT LEADER + 0x2026,0x8163, // HORIZONTAL ELLIPSIS + 0x2030,0x81F1, // PER MILLE SIGN + 0x2032,0x818C, // PRIME + 0x2033,0x818D, // DOUBLE PRIME + 0x203B,0x81A6, // REFERENCE MARK + 0x2103,0x818E, // DEGREE CELSIUS + 0x212B,0x81F0, // ANGSTROM SIGN + 0x2190,0x81A9, // LEFTWARDS ARROW + 0x2191,0x81AA, // UPWARDS ARROW + 0x2192,0x81A8, // RIGHTWARDS ARROW + 0x2193,0x81AB, // DOWNWARDS ARROW + 0x21D2,0x81CB, // RIGHTWARDS DOUBLE ARROW + 0x21D4,0x81CC, // LEFT RIGHT DOUBLE ARROW + 0x2200,0x81CD, // FOR ALL + 0x2202,0x81DD, // PARTIAL DIFFERENTIAL + 0x2203,0x81CE, // THERE EXISTS + 0x2207,0x81DE, // NABLA + 0x2208,0x81B8, // ELEMENT OF + 0x220B,0x81B9, // CONTAINS AS MEMBER + 0x2212,0x817C, // MINUS SIGN + 0x221A,0x81E3, // SQUARE ROOT + 0x221D,0x81E5, // PROPORTIONAL TO + 0x221E,0x8187, // INFINITY + 0x2220,0x81DA, // ANGLE + 0x2227,0x81C8, // LOGICAL AND + 0x2228,0x81C9, // LOGICAL OR + 0x2229,0x81BF, // INTERSECTION + 0x222A,0x81BE, // UNION + 0x222B,0x81E7, // INTEGRAL + 0x222C,0x81E8, // DOUBLE INTEGRAL + 0x2234,0x8188, // THEREFORE + 0x2235,0x81E6, // BECAUSE + 0x223D,0x81E4, // REVERSED TILDE + 0x2252,0x81E0, // APPROXIMATELY EQUAL TO OR THE IMAGE OF + 0x2260,0x8182, // NOT EQUAL TO + 0x2261,0x81DF, // IDENTICAL TO + 0x2266,0x8185, // LESS-THAN OVER EQUAL TO + 0x2267,0x8186, // GREATER-THAN OVER EQUAL TO + 0x226A,0x81E1, // MUCH LESS-THAN + 0x226B,0x81E2, // MUCH GREATER-THAN + 0x2282,0x81BC, // SUBSET OF + 0x2283,0x81BD, // SUPERSET OF + 0x2286,0x81BA, // SUBSET OF OR EQUAL TO + 0x2287,0x81BB, // SUPERSET OF OR EQUAL TO + 0x22A5,0x81DB, // UP TACK + 0x2312,0x81DC, // ARC + 0x2500,0x849F, // BOX DRAWINGS LIGHT HORIZONTAL + 0x2501,0x84AA, // BOX DRAWINGS HEAVY HORIZONTAL + 0x2502,0x84A0, // BOX DRAWINGS LIGHT VERTICAL + 0x2503,0x84AB, // BOX DRAWINGS HEAVY VERTICAL + 0x250C,0x84A1, // BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x250F,0x84AC, // BOX DRAWINGS HEAVY DOWN AND RIGHT + 0x2510,0x84A2, // BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2513,0x84AD, // BOX DRAWINGS HEAVY DOWN AND LEFT + 0x2514,0x84A4, // BOX DRAWINGS LIGHT UP AND RIGHT + 0x2517,0x84AF, // BOX DRAWINGS HEAVY UP AND RIGHT + 0x2518,0x84A3, // BOX DRAWINGS LIGHT UP AND LEFT + 0x251B,0x84AE, // BOX DRAWINGS HEAVY UP AND LEFT + 0x251C,0x84A5, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x251D,0x84BA, // BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + 0x2520,0x84B5, // BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + 0x2523,0x84B0, // BOX DRAWINGS HEAVY VERTICAL AND RIGHT + 0x2524,0x84A7, // BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x2525,0x84BC, // BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + 0x2528,0x84B7, // BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + 0x252B,0x84B2, // BOX DRAWINGS HEAVY VERTICAL AND LEFT + 0x252C,0x84A6, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x252F,0x84B6, // BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + 0x2530,0x84BB, // BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + 0x2533,0x84B1, // BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + 0x2534,0x84A8, // BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x2537,0x84B8, // BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + 0x2538,0x84BD, // BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + 0x253B,0x84B3, // BOX DRAWINGS HEAVY UP AND HORIZONTAL + 0x253C,0x84A9, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x253F,0x84B9, // BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + 0x2542,0x84BE, // BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + 0x254B,0x84B4, // BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + 0x25A0,0x81A1, // BLACK SQUARE + 0x25A1,0x81A0, // WHITE SQUARE + 0x25B2,0x81A3, // BLACK UP-POINTING TRIANGLE + 0x25B3,0x81A2, // WHITE UP-POINTING TRIANGLE + 0x25BC,0x81A5, // BLACK DOWN-POINTING TRIANGLE + 0x25BD,0x81A4, // WHITE DOWN-POINTING TRIANGLE + 0x25C6,0x819F, // BLACK DIAMOND + 0x25C7,0x819E, // WHITE DIAMOND + 0x25CB,0x819B, // WHITE CIRCLE + 0x25CE,0x819D, // BULLSEYE + 0x25CF,0x819C, // BLACK CIRCLE + 0x25EF,0x81FC, // LARGE CIRCLE + 0x2605,0x819A, // BLACK STAR + 0x2606,0x8199, // WHITE STAR + 0x2640,0x818A, // FEMALE SIGN + 0x2642,0x8189, // MALE SIGN + 0x266A,0x81F4, // EIGHTH NOTE + 0x266D,0x81F3, // MUSIC FLAT SIGN + 0x266F,0x81F2, // MUSIC SHARP SIGN + 0x3000,0x8140, // IDEOGRAPHIC SPACE + 0x3001,0x8141, // IDEOGRAPHIC COMMA + 0x3002,0x8142, // IDEOGRAPHIC FULL STOP + 0x3003,0x8156, // DITTO MARK + 0x3005,0x8158, // IDEOGRAPHIC ITERATION MARK + 0x3006,0x8159, // IDEOGRAPHIC CLOSING MARK + 0x3007,0x815A, // IDEOGRAPHIC NUMBER ZERO + 0x3008,0x8171, // LEFT ANGLE BRACKET + 0x3009,0x8172, // RIGHT ANGLE BRACKET + 0x300A,0x8173, // LEFT DOUBLE ANGLE BRACKET + 0x300B,0x8174, // RIGHT DOUBLE ANGLE BRACKET + 0x300C,0x8175, // LEFT CORNER BRACKET + 0x300D,0x8176, // RIGHT CORNER BRACKET + 0x300E,0x8177, // LEFT WHITE CORNER BRACKET + 0x300F,0x8178, // RIGHT WHITE CORNER BRACKET + 0x3010,0x8179, // LEFT BLACK LENTICULAR BRACKET + 0x3011,0x817A, // RIGHT BLACK LENTICULAR BRACKET + 0x3012,0x81A7, // POSTAL MARK + 0x3013,0x81AC, // GETA MARK + 0x3014,0x816B, // LEFT TORTOISE SHELL BRACKET + 0x3015,0x816C, // RIGHT TORTOISE SHELL BRACKET + 0x301C,0x8160, // WAVE DASH + 0x3041,0x829F, // HIRAGANA LETTER SMALL A + 0x3042,0x82A0, // HIRAGANA LETTER A + 0x3043,0x82A1, // HIRAGANA LETTER SMALL I + 0x3044,0x82A2, // HIRAGANA LETTER I + 0x3045,0x82A3, // HIRAGANA LETTER SMALL U + 0x3046,0x82A4, // HIRAGANA LETTER U + 0x3047,0x82A5, // HIRAGANA LETTER SMALL E + 0x3048,0x82A6, // HIRAGANA LETTER E + 0x3049,0x82A7, // HIRAGANA LETTER SMALL O + 0x304A,0x82A8, // HIRAGANA LETTER O + 0x304B,0x82A9, // HIRAGANA LETTER KA + 0x304C,0x82AA, // HIRAGANA LETTER GA + 0x304D,0x82AB, // HIRAGANA LETTER KI + 0x304E,0x82AC, // HIRAGANA LETTER GI + 0x304F,0x82AD, // HIRAGANA LETTER KU + 0x3050,0x82AE, // HIRAGANA LETTER GU + 0x3051,0x82AF, // HIRAGANA LETTER KE + 0x3052,0x82B0, // HIRAGANA LETTER GE + 0x3053,0x82B1, // HIRAGANA LETTER KO + 0x3054,0x82B2, // HIRAGANA LETTER GO + 0x3055,0x82B3, // HIRAGANA LETTER SA + 0x3056,0x82B4, // HIRAGANA LETTER ZA + 0x3057,0x82B5, // HIRAGANA LETTER SI + 0x3058,0x82B6, // HIRAGANA LETTER ZI + 0x3059,0x82B7, // HIRAGANA LETTER SU + 0x305A,0x82B8, // HIRAGANA LETTER ZU + 0x305B,0x82B9, // HIRAGANA LETTER SE + 0x305C,0x82BA, // HIRAGANA LETTER ZE + 0x305D,0x82BB, // HIRAGANA LETTER SO + 0x305E,0x82BC, // HIRAGANA LETTER ZO + 0x305F,0x82BD, // HIRAGANA LETTER TA + 0x3060,0x82BE, // HIRAGANA LETTER DA + 0x3061,0x82BF, // HIRAGANA LETTER TI + 0x3062,0x82C0, // HIRAGANA LETTER DI + 0x3063,0x82C1, // HIRAGANA LETTER SMALL TU + 0x3064,0x82C2, // HIRAGANA LETTER TU + 0x3065,0x82C3, // HIRAGANA LETTER DU + 0x3066,0x82C4, // HIRAGANA LETTER TE + 0x3067,0x82C5, // HIRAGANA LETTER DE + 0x3068,0x82C6, // HIRAGANA LETTER TO + 0x3069,0x82C7, // HIRAGANA LETTER DO + 0x306A,0x82C8, // HIRAGANA LETTER NA + 0x306B,0x82C9, // HIRAGANA LETTER NI + 0x306C,0x82CA, // HIRAGANA LETTER NU + 0x306D,0x82CB, // HIRAGANA LETTER NE + 0x306E,0x82CC, // HIRAGANA LETTER NO + 0x306F,0x82CD, // HIRAGANA LETTER HA + 0x3070,0x82CE, // HIRAGANA LETTER BA + 0x3071,0x82CF, // HIRAGANA LETTER PA + 0x3072,0x82D0, // HIRAGANA LETTER HI + 0x3073,0x82D1, // HIRAGANA LETTER BI + 0x3074,0x82D2, // HIRAGANA LETTER PI + 0x3075,0x82D3, // HIRAGANA LETTER HU + 0x3076,0x82D4, // HIRAGANA LETTER BU + 0x3077,0x82D5, // HIRAGANA LETTER PU + 0x3078,0x82D6, // HIRAGANA LETTER HE + 0x3079,0x82D7, // HIRAGANA LETTER BE + 0x307A,0x82D8, // HIRAGANA LETTER PE + 0x307B,0x82D9, // HIRAGANA LETTER HO + 0x307C,0x82DA, // HIRAGANA LETTER BO + 0x307D,0x82DB, // HIRAGANA LETTER PO + 0x307E,0x82DC, // HIRAGANA LETTER MA + 0x307F,0x82DD, // HIRAGANA LETTER MI + 0x3080,0x82DE, // HIRAGANA LETTER MU + 0x3081,0x82DF, // HIRAGANA LETTER ME + 0x3082,0x82E0, // HIRAGANA LETTER MO + 0x3083,0x82E1, // HIRAGANA LETTER SMALL YA + 0x3084,0x82E2, // HIRAGANA LETTER YA + 0x3085,0x82E3, // HIRAGANA LETTER SMALL YU + 0x3086,0x82E4, // HIRAGANA LETTER YU + 0x3087,0x82E5, // HIRAGANA LETTER SMALL YO + 0x3088,0x82E6, // HIRAGANA LETTER YO + 0x3089,0x82E7, // HIRAGANA LETTER RA + 0x308A,0x82E8, // HIRAGANA LETTER RI + 0x308B,0x82E9, // HIRAGANA LETTER RU + 0x308C,0x82EA, // HIRAGANA LETTER RE + 0x308D,0x82EB, // HIRAGANA LETTER RO + 0x308E,0x82EC, // HIRAGANA LETTER SMALL WA + 0x308F,0x82ED, // HIRAGANA LETTER WA + 0x3090,0x82EE, // HIRAGANA LETTER WI + 0x3091,0x82EF, // HIRAGANA LETTER WE + 0x3092,0x82F0, // HIRAGANA LETTER WO + 0x3093,0x82F1, // HIRAGANA LETTER N + 0x309B,0x814A, // KATAKANA-HIRAGANA VOICED SOUND MARK + 0x309C,0x814B, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + 0x309D,0x8154, // HIRAGANA ITERATION MARK + 0x309E,0x8155, // HIRAGANA VOICED ITERATION MARK + 0x30A1,0x8340, // KATAKANA LETTER SMALL A + 0x30A2,0x8341, // KATAKANA LETTER A + 0x30A3,0x8342, // KATAKANA LETTER SMALL I + 0x30A4,0x8343, // KATAKANA LETTER I + 0x30A5,0x8344, // KATAKANA LETTER SMALL U + 0x30A6,0x8345, // KATAKANA LETTER U + 0x30A7,0x8346, // KATAKANA LETTER SMALL E + 0x30A8,0x8347, // KATAKANA LETTER E + 0x30A9,0x8348, // KATAKANA LETTER SMALL O + 0x30AA,0x8349, // KATAKANA LETTER O + 0x30AB,0x834A, // KATAKANA LETTER KA + 0x30AC,0x834B, // KATAKANA LETTER GA + 0x30AD,0x834C, // KATAKANA LETTER KI + 0x30AE,0x834D, // KATAKANA LETTER GI + 0x30AF,0x834E, // KATAKANA LETTER KU + 0x30B0,0x834F, // KATAKANA LETTER GU + 0x30B1,0x8350, // KATAKANA LETTER KE + 0x30B2,0x8351, // KATAKANA LETTER GE + 0x30B3,0x8352, // KATAKANA LETTER KO + 0x30B4,0x8353, // KATAKANA LETTER GO + 0x30B5,0x8354, // KATAKANA LETTER SA + 0x30B6,0x8355, // KATAKANA LETTER ZA + 0x30B7,0x8356, // KATAKANA LETTER SI + 0x30B8,0x8357, // KATAKANA LETTER ZI + 0x30B9,0x8358, // KATAKANA LETTER SU + 0x30BA,0x8359, // KATAKANA LETTER ZU + 0x30BB,0x835A, // KATAKANA LETTER SE + 0x30BD,0x835C, // KATAKANA LETTER SO + 0x30BE,0x835D, // KATAKANA LETTER ZO + 0x30BF,0x835E, // KATAKANA LETTER TA + 0x30C0,0x835F, // KATAKANA LETTER DA + 0x30C1,0x8360, // KATAKANA LETTER TI + 0x30C2,0x8361, // KATAKANA LETTER DI + 0x30C3,0x8362, // KATAKANA LETTER SMALL TU + 0x30C4,0x8363, // KATAKANA LETTER TU + 0x30C5,0x8364, // KATAKANA LETTER DU + 0x30C6,0x8365, // KATAKANA LETTER TE + 0x30C7,0x8366, // KATAKANA LETTER DE + 0x30C8,0x8367, // KATAKANA LETTER TO + 0x30C9,0x8368, // KATAKANA LETTER DO + 0x30CA,0x8369, // KATAKANA LETTER NA + 0x30CB,0x836A, // KATAKANA LETTER NI + 0x30CC,0x836B, // KATAKANA LETTER NU + 0x30CD,0x836C, // KATAKANA LETTER NE + 0x30CE,0x836D, // KATAKANA LETTER NO + 0x30CF,0x836E, // KATAKANA LETTER HA + 0x30D0,0x836F, // KATAKANA LETTER BA + 0x30D1,0x8370, // KATAKANA LETTER PA + 0x30D2,0x8371, // KATAKANA LETTER HI + 0x30D3,0x8372, // KATAKANA LETTER BI + 0x30D4,0x8373, // KATAKANA LETTER PI + 0x30D5,0x8374, // KATAKANA LETTER HU + 0x30D6,0x8375, // KATAKANA LETTER BU + 0x30D7,0x8376, // KATAKANA LETTER PU + 0x30D8,0x8377, // KATAKANA LETTER HE + 0x30D9,0x8378, // KATAKANA LETTER BE + 0x30DA,0x8379, // KATAKANA LETTER PE + 0x30DB,0x837A, // KATAKANA LETTER HO + 0x30DC,0x837B, // KATAKANA LETTER BO + 0x30DD,0x837C, // KATAKANA LETTER PO + 0x30DE,0x837D, // KATAKANA LETTER MA + 0x30DF,0x837E, // KATAKANA LETTER MI + 0x30E0,0x8380, // KATAKANA LETTER MU + 0x30E1,0x8381, // KATAKANA LETTER ME + 0x30E2,0x8382, // KATAKANA LETTER MO + 0x30E3,0x8383, // KATAKANA LETTER SMALL YA + 0x30E4,0x8384, // KATAKANA LETTER YA + 0x30E5,0x8385, // KATAKANA LETTER SMALL YU + 0x30E6,0x8386, // KATAKANA LETTER YU + 0x30E7,0x8387, // KATAKANA LETTER SMALL YO + 0x30E8,0x8388, // KATAKANA LETTER YO + 0x30E9,0x8389, // KATAKANA LETTER RA + 0x30EA,0x838A, // KATAKANA LETTER RI + 0x30EB,0x838B, // KATAKANA LETTER RU + 0x30EC,0x838C, // KATAKANA LETTER RE + 0x30ED,0x838D, // KATAKANA LETTER RO + 0x30EE,0x838E, // KATAKANA LETTER SMALL WA + 0x30EF,0x838F, // KATAKANA LETTER WA + 0x30F0,0x8390, // KATAKANA LETTER WI + 0x30F1,0x8391, // KATAKANA LETTER WE + 0x30F2,0x8392, // KATAKANA LETTER WO + 0x30F3,0x8393, // KATAKANA LETTER N + 0x30F4,0x8394, // KATAKANA LETTER VU + 0x30F5,0x8395, // KATAKANA LETTER SMALL KA + 0x30F6,0x8396, // KATAKANA LETTER SMALL KE + 0x30FB,0x8145, // KATAKANA MIDDLE DOT + 0x30FD,0x8152, // KATAKANA ITERATION MARK + 0x30FE,0x8153, // KATAKANA VOICED ITERATION MARK + 0x4E00,0x88EA, // + 0x4E01,0x929A, // + 0x4E03,0x8EB5, // + 0x4E07,0x969C, // + 0x4E08,0x8FE4, // + 0x4E09,0x8E4F, // + 0x4E0A,0x8FE3, // + 0x4E0B,0x89BA, // + 0x4E0D,0x9573, // + 0x4E0E,0x975E, // + 0x4E10,0x98A0, // + 0x4E11,0x894E, // + 0x4E14,0x8A8E, // + 0x4E15,0x98A1, // + 0x4E16,0x90A2, // + 0x4E17,0x99C0, // + 0x4E18,0x8B75, // + 0x4E19,0x95B8, // + 0x4E1E,0x8FE5, // + 0x4E21,0x97BC, // + 0x4E26,0x95C0, // + 0x4E2A,0x98A2, // + 0x4E2D,0x9286, // + 0x4E31,0x98A3, // + 0x4E32,0x8BF8, // + 0x4E36,0x98A4, // + 0x4E38,0x8ADB, // + 0x4E39,0x924F, // + 0x4E3B,0x8EE5, // + 0x4E3C,0x98A5, // + 0x4E3F,0x98A6, // + 0x4E42,0x98A7, // + 0x4E43,0x9454, // + 0x4E45,0x8B76, // + 0x4E4B,0x9456, // + 0x4E4D,0x93E1, // + 0x4E4E,0x8CC1, // + 0x4E4F,0x9652, // + 0x4E55,0xE568, // + 0x4E56,0x98A8, // + 0x4E57,0x8FE6, // + 0x4E58,0x98A9, // + 0x4E59,0x89B3, // + 0x4E5D,0x8BE3, // + 0x4E5E,0x8CEE, // + 0x4E5F,0x96E7, // + 0x4E62,0x9BA4, // + 0x4E71,0x9790, // + 0x4E73,0x93FB, // + 0x4E7E,0x8AA3, // + 0x4E80,0x8B54, // + 0x4E82,0x98AA, // + 0x4E85,0x98AB, // + 0x4E86,0x97B9, // + 0x4E88,0x975C, // + 0x4E89,0x9188, // + 0x4E8A,0x98AD, // + 0x4E8B,0x8E96, // + 0x4E8C,0x93F1, // + 0x4E8E,0x98B0, // + 0x4E91,0x895D, // + 0x4E92,0x8CDD, // + 0x4E94,0x8CDC, // + 0x4E95,0x88E4, // + 0x4E98,0x986A, // + 0x4E99,0x9869, // + 0x4E9B,0x8DB1, // + 0x4E9C,0x889F, // + 0x4E9E,0x98B1, // + 0x4E9F,0x98B2, // + 0x4EA0,0x98B3, // + 0x4EA1,0x9653, // + 0x4EA2,0x98B4, // + 0x4EA4,0x8CF0, // + 0x4EA5,0x88E5, // + 0x4EA6,0x9692, // + 0x4EA8,0x8B9C, // + 0x4EAB,0x8B9D, // + 0x4EAC,0x8B9E, // + 0x4EAD,0x92E0, // + 0x4EAE,0x97BA, // + 0x4EB0,0x98B5, // + 0x4EB3,0x98B6, // + 0x4EB6,0x98B7, // + 0x4EBA,0x906C, // + 0x4EC0,0x8F59, // + 0x4EC1,0x906D, // + 0x4EC2,0x98BC, // + 0x4EC4,0x98BA, // + 0x4EC6,0x98BB, // + 0x4EC7,0x8B77, // + 0x4ECA,0x8DA1, // + 0x4ECB,0x89EE, // + 0x4ECD,0x98B9, // + 0x4ECE,0x98B8, // + 0x4ECF,0x95A7, // + 0x4ED4,0x8E65, // + 0x4ED5,0x8E64, // + 0x4ED6,0x91BC, // + 0x4ED7,0x98BD, // + 0x4ED8,0x9574, // + 0x4ED9,0x90E5, // + 0x4EDD,0x8157, // + 0x4EDE,0x98BE, // + 0x4EDF,0x98C0, // + 0x4EE3,0x91E3, // + 0x4EE4,0x97DF, // + 0x4EE5,0x88C8, // + 0x4EED,0x98BF, // + 0x4EEE,0x89BC, // + 0x4EF0,0x8BC2, // + 0x4EF2,0x9287, // + 0x4EF6,0x8C8F, // + 0x4EF7,0x98C1, // + 0x4EFB,0x9443, // + 0x4F01,0x8AE9, // + 0x4F09,0x98C2, // + 0x4F0A,0x88C9, // + 0x4F0D,0x8CDE, // + 0x4F0E,0x8AEA, // + 0x4F0F,0x959A, // + 0x4F10,0x94B0, // + 0x4F11,0x8B78, // + 0x4F1A,0x89EF, // + 0x4F1C,0x98E5, // + 0x4F1D,0x9360, // + 0x4F2F,0x948C, // + 0x4F30,0x98C4, // + 0x4F34,0x94BA, // + 0x4F36,0x97E0, // + 0x4F38,0x904C, // + 0x4F3A,0x8E66, // + 0x4F3C,0x8E97, // + 0x4F3D,0x89BE, // + 0x4F43,0x92CF, // + 0x4F46,0x9241, // + 0x4F47,0x98C8, // + 0x4F4D,0x88CA, // + 0x4F4E,0x92E1, // + 0x4F4F,0x8F5A, // + 0x4F50,0x8DB2, // + 0x4F51,0x9743, // + 0x4F53,0x91CC, // + 0x4F55,0x89BD, // + 0x4F57,0x98C7, // + 0x4F59,0x975D, // + 0x4F5A,0x98C3, // + 0x4F5B,0x98C5, // + 0x4F5C,0x8DEC, // + 0x4F5D,0x98C6, // + 0x4F5E,0x9B43, // + 0x4F69,0x98CE, // + 0x4F6F,0x98D1, // + 0x4F70,0x98CF, // + 0x4F73,0x89C0, // + 0x4F75,0x95B9, // + 0x4F76,0x98C9, // + 0x4F7B,0x98CD, // + 0x4F7C,0x8CF1, // + 0x4F7F,0x8E67, // + 0x4F83,0x8AA4, // + 0x4F86,0x98D2, // + 0x4F88,0x98CA, // + 0x4F8B,0x97E1, // + 0x4F8D,0x8E98, // + 0x4F8F,0x98CB, // + 0x4F91,0x98D0, // + 0x4F96,0x98D3, // + 0x4F98,0x98CC, // + 0x4F9B,0x8B9F, // + 0x4F9D,0x88CB, // + 0x4FA0,0x8BA0, // + 0x4FA1,0x89BF, // + 0x4FAB,0x9B44, // + 0x4FAD,0x9699, // + 0x4FAE,0x958E, // + 0x4FAF,0x8CF2, // + 0x4FB5,0x904E, // + 0x4FB6,0x97B5, // + 0x4FBF,0x95D6, // + 0x4FC2,0x8C57, // + 0x4FC3,0x91A3, // + 0x4FC4,0x89E2, // + 0x4FCA,0x8F72, // + 0x4FCE,0x98D7, // + 0x4FD0,0x98DC, // + 0x4FD1,0x98DA, // + 0x4FD4,0x98D5, // + 0x4FD7,0x91AD, // + 0x4FD8,0x98D8, // + 0x4FDA,0x98DB, // + 0x4FDB,0x98D9, // + 0x4FDD,0x95DB, // + 0x4FDF,0x98D6, // + 0x4FE1,0x904D, // + 0x4FE3,0x9693, // + 0x4FE4,0x98DD, // + 0x4FE5,0x98DE, // + 0x4FEE,0x8F43, // + 0x4FEF,0x98EB, // + 0x4FF3,0x946F, // + 0x4FF5,0x9555, // + 0x4FF6,0x98E6, // + 0x4FF8,0x95EE, // + 0x4FFA,0x89B4, // + 0x4FFE,0x98EA, // + 0x5005,0x98E4, // + 0x5006,0x98ED, // + 0x5009,0x9171, // + 0x500B,0x8CC2, // + 0x500D,0x947B, // + 0x500F,0xE0C5, // + 0x5011,0x98EC, // + 0x5012,0x937C, // + 0x5014,0x98E1, // + 0x5016,0x8CF4, // + 0x5019,0x8CF3, // + 0x501A,0x98DF, // + 0x501F,0x8ED8, // + 0x5021,0x98E7, // + 0x5023,0x95ED, // + 0x5024,0x926C, // + 0x5025,0x98E3, // + 0x5026,0x8C91, // + 0x5028,0x98E0, // + 0x5029,0x98E8, // + 0x502A,0x98E2, // + 0x502B,0x97CF, // + 0x502C,0x98E9, // + 0x502D,0x9860, // + 0x5036,0x8BE4, // + 0x5039,0x8C90, // + 0x5043,0x98EE, // + 0x5047,0x98EF, // + 0x5048,0x98F3, // + 0x5049,0x88CC, // + 0x504F,0x95CE, // + 0x5050,0x98F2, // + 0x5055,0x98F1, // + 0x5056,0x98F5, // + 0x505A,0x98F4, // + 0x505C,0x92E2, // + 0x5065,0x8C92, // + 0x506C,0x98F6, // + 0x5072,0x8EC3, // + 0x5074,0x91A4, // + 0x5075,0x92E3, // + 0x5076,0x8BF4, // + 0x5078,0x98F7, // + 0x507D,0x8B55, // + 0x5080,0x98F8, // + 0x5085,0x98FA, // + 0x508D,0x9654, // + 0x5091,0x8C86, // + 0x5098,0x8E50, // + 0x5099,0x94F5, // + 0x509A,0x98F9, // + 0x50AC,0x8DC3, // + 0x50AD,0x9762, // + 0x50B2,0x98FC, // + 0x50B3,0x9942, // + 0x50B4,0x98FB, // + 0x50B5,0x8DC2, // + 0x50B7,0x8F9D, // + 0x50BE,0x8C58, // + 0x50C2,0x9943, // + 0x50C5,0x8BCD, // + 0x50C9,0x9940, // + 0x50CA,0x9941, // + 0x50CD,0x93AD, // + 0x50CF,0x919C, // + 0x50D1,0x8BA1, // + 0x50D5,0x966C, // + 0x50D6,0x9944, // + 0x50DA,0x97BB, // + 0x50DE,0x9945, // + 0x50E3,0x9948, // + 0x50E5,0x9946, // + 0x50E7,0x916D, // + 0x50ED,0x9947, // + 0x50EE,0x9949, // + 0x50F5,0x994B, // + 0x50F9,0x994A, // + 0x50FB,0x95C6, // + 0x5100,0x8B56, // + 0x5101,0x994D, // + 0x5102,0x994E, // + 0x5104,0x89AD, // + 0x5109,0x994C, // + 0x5112,0x8EF2, // + 0x5114,0x9951, // + 0x5115,0x9950, // + 0x5116,0x994F, // + 0x5118,0x98D4, // + 0x511A,0x9952, // + 0x511F,0x8F9E, // + 0x5121,0x9953, // + 0x512A,0x9744, // + 0x5132,0x96D7, // + 0x5137,0x9955, // + 0x513A,0x9954, // + 0x513B,0x9957, // + 0x513C,0x9956, // + 0x513F,0x9958, // + 0x5140,0x9959, // + 0x5141,0x88F2, // + 0x5143,0x8CB3, // + 0x5144,0x8C5A, // + 0x5146,0x929B, // + 0x5147,0x8BA2, // + 0x5148,0x90E6, // + 0x5149,0x8CF5, // + 0x514B,0x8D8E, // + 0x514D,0x96C6, // + 0x514E,0x9365, // + 0x5150,0x8E99, // + 0x5152,0x995A, // + 0x5154,0x995C, // + 0x515A,0x937D, // + 0x515C,0x8A95, // + 0x5162,0x995D, // + 0x5165,0x93FC, // + 0x5168,0x9153, // + 0x5169,0x995F, // + 0x516A,0x9960, // + 0x516B,0x94AA, // + 0x516C,0x8CF6, // + 0x516D,0x985A, // + 0x516E,0x9961, // + 0x5171,0x8BA4, // + 0x5175,0x95BA, // + 0x5176,0x91B4, // + 0x5177,0x8BEF, // + 0x5178,0x9354, // + 0x517C,0x8C93, // + 0x5180,0x9962, // + 0x5182,0x9963, // + 0x5185,0x93E0, // + 0x5186,0x897E, // + 0x5189,0x9966, // + 0x518A,0x8DFB, // + 0x518C,0x9965, // + 0x518D,0x8DC4, // + 0x518F,0x9967, // + 0x5190,0xE3EC, // + 0x5191,0x9968, // + 0x5192,0x9660, // + 0x5193,0x9969, // + 0x5195,0x996A, // + 0x5196,0x996B, // + 0x5197,0x8FE7, // + 0x5199,0x8ECA, // + 0x51A0,0x8AA5, // + 0x51A2,0x996E, // + 0x51A4,0x996C, // + 0x51A5,0x96BB, // + 0x51A6,0x996D, // + 0x51A8,0x9579, // + 0x51A9,0x996F, // + 0x51AA,0x9970, // + 0x51AB,0x9971, // + 0x51AC,0x937E, // + 0x51B0,0x9975, // + 0x51B1,0x9973, // + 0x51B2,0x9974, // + 0x51B3,0x9972, // + 0x51B4,0x8DE1, // + 0x51B5,0x9976, // + 0x51B6,0x96E8, // + 0x51B7,0x97E2, // + 0x51BD,0x9977, // + 0x51C4,0x90A6, // + 0x51C5,0x9978, // + 0x51C6,0x8F79, // + 0x51C9,0x9979, // + 0x51CB,0x929C, // + 0x51CC,0x97BD, // + 0x51CD,0x9380, // + 0x51D6,0x99C3, // + 0x51DB,0x997A, // + 0x51DC,0xEAA3, // + 0x51DD,0x8BC3, // + 0x51E0,0x997B, // + 0x51E1,0x967D, // + 0x51E6,0x8F88, // + 0x51E7,0x91FA, // + 0x51E9,0x997D, // + 0x51EA,0x93E2, // + 0x51ED,0x997E, // + 0x51F0,0x9980, // + 0x51F1,0x8A4D, // + 0x51F5,0x9981, // + 0x51F6,0x8BA5, // + 0x51F8,0x93CA, // + 0x51F9,0x899A, // + 0x51FA,0x8F6F, // + 0x51FD,0x949F, // + 0x51FE,0x9982, // + 0x5200,0x9381, // + 0x5203,0x906E, // + 0x5204,0x9983, // + 0x5206,0x95AA, // + 0x5207,0x90D8, // + 0x5208,0x8AA0, // + 0x520A,0x8AA7, // + 0x520B,0x9984, // + 0x520E,0x9986, // + 0x5211,0x8C59, // + 0x5214,0x9985, // + 0x5217,0x97F1, // + 0x521D,0x8F89, // + 0x5224,0x94BB, // + 0x5225,0x95CA, // + 0x5227,0x9987, // + 0x5229,0x9798, // + 0x522A,0x9988, // + 0x522E,0x9989, // + 0x5230,0x939E, // + 0x5233,0x998A, // + 0x5236,0x90A7, // + 0x5237,0x8DFC, // + 0x5238,0x8C94, // + 0x5239,0x998B, // + 0x523A,0x8E68, // + 0x523B,0x8D8F, // + 0x5243,0x92E4, // + 0x5244,0x998D, // + 0x5247,0x91A5, // + 0x524A,0x8DED, // + 0x524B,0x998E, // + 0x524C,0x998F, // + 0x524D,0x914F, // + 0x524F,0x998C, // + 0x5254,0x9991, // + 0x5256,0x9655, // + 0x525B,0x8D84, // + 0x525E,0x9990, // + 0x5263,0x8C95, // + 0x5264,0x8DDC, // + 0x5265,0x948D, // + 0x5269,0x9994, // + 0x526A,0x9992, // + 0x526F,0x959B, // + 0x5270,0x8FE8, // + 0x5271,0x999B, // + 0x5272,0x8A84, // + 0x5273,0x9995, // + 0x5274,0x9993, // + 0x5275,0x916E, // + 0x527D,0x9997, // + 0x527F,0x9996, // + 0x5283,0x8A63, // + 0x5287,0x8C80, // + 0x5288,0x999C, // + 0x5289,0x97AB, // + 0x528D,0x9998, // + 0x5291,0x999D, // + 0x5292,0x999A, // + 0x5294,0x9999, // + 0x529B,0x97CD, // + 0x529F,0x8CF7, // + 0x52A0,0x89C1, // + 0x52A3,0x97F2, // + 0x52A9,0x8F95, // + 0x52AA,0x9377, // + 0x52AB,0x8D85, // + 0x52AC,0x99A0, // + 0x52AD,0x99A1, // + 0x52B1,0x97E3, // + 0x52B4,0x984A, // + 0x52B5,0x99A3, // + 0x52B9,0x8CF8, // + 0x52BC,0x99A2, // + 0x52BE,0x8A4E, // + 0x52C1,0x99A4, // + 0x52C3,0x9675, // + 0x52C5,0x92BA, // + 0x52C7,0x9745, // + 0x52C9,0x95D7, // + 0x52CD,0x99A5, // + 0x52D2,0xE8D3, // + 0x52D5,0x93AE, // + 0x52D7,0x99A6, // + 0x52D8,0x8AA8, // + 0x52D9,0x96B1, // + 0x52DD,0x8F9F, // + 0x52DE,0x99A7, // + 0x52DF,0x95E5, // + 0x52E0,0x99AB, // + 0x52E2,0x90A8, // + 0x52E3,0x99A8, // + 0x52E4,0x8BCE, // + 0x52E6,0x99A9, // + 0x52E7,0x8AA9, // + 0x52F2,0x8C4D, // + 0x52F3,0x99AC, // + 0x52F5,0x99AD, // + 0x52F8,0x99AE, // + 0x52F9,0x99AF, // + 0x52FA,0x8ED9, // + 0x52FE,0x8CF9, // + 0x52FF,0x96DC, // + 0x5301,0x96E6, // + 0x5302,0x93F5, // + 0x5305,0x95EF, // + 0x5306,0x99B0, // + 0x5308,0x99B1, // + 0x530D,0x99B3, // + 0x530F,0x99B5, // + 0x5310,0x99B4, // + 0x5315,0x99B6, // + 0x5316,0x89BB, // + 0x5317,0x966B, // + 0x5319,0x8DFA, // + 0x531A,0x99B7, // + 0x531D,0x9178, // + 0x5320,0x8FA0, // + 0x5321,0x8BA7, // + 0x5323,0x99B8, // + 0x532A,0x94D9, // + 0x532F,0x99B9, // + 0x5331,0x99BA, // + 0x5333,0x99BB, // + 0x5338,0x99BC, // + 0x5339,0x9543, // + 0x533A,0x8BE6, // + 0x533B,0x88E3, // + 0x533F,0x93BD, // + 0x5340,0x99BD, // + 0x5341,0x8F5C, // + 0x5343,0x90E7, // + 0x5345,0x99BF, // + 0x5346,0x99BE, // + 0x5347,0x8FA1, // + 0x5348,0x8CDF, // + 0x5349,0x99C1, // + 0x534A,0x94BC, // + 0x534D,0x99C2, // + 0x5351,0x94DA, // + 0x5352,0x91B2, // + 0x5353,0x91EC, // + 0x5354,0x8BA6, // + 0x5357,0x93EC, // + 0x5358,0x9250, // + 0x535A,0x948E, // + 0x535C,0x966D, // + 0x535E,0x99C4, // + 0x5360,0x90E8, // + 0x5366,0x8C54, // + 0x5369,0x99C5, // + 0x536E,0x99C6, // + 0x536F,0x894B, // + 0x5370,0x88F3, // + 0x5371,0x8AEB, // + 0x5373,0x91A6, // + 0x5374,0x8B70, // + 0x5375,0x9791, // + 0x5377,0x99C9, // + 0x5378,0x89B5, // + 0x537B,0x99C8, // + 0x537F,0x8BA8, // + 0x5382,0x99CA, // + 0x5384,0x96EF, // + 0x5396,0x99CB, // + 0x5398,0x97D0, // + 0x539A,0x8CFA, // + 0x539F,0x8CB4, // + 0x53A0,0x99CC, // + 0x53A5,0x99CE, // + 0x53A6,0x99CD, // + 0x53A8,0x907E, // + 0x53A9,0x8958, // + 0x53AD,0x897D, // + 0x53AE,0x99CF, // + 0x53B0,0x99D0, // + 0x53B3,0x8CB5, // + 0x53B6,0x99D1, // + 0x53BB,0x8B8E, // + 0x53C2,0x8E51, // + 0x53C3,0x99D2, // + 0x53C8,0x9694, // + 0x53C9,0x8DB3, // + 0x53CA,0x8B79, // + 0x53CB,0x9746, // + 0x53CC,0x916F, // + 0x53CD,0x94BD, // + 0x53CE,0x8EFB, // + 0x53D4,0x8F66, // + 0x53D6,0x8EE6, // + 0x53D7,0x8EF3, // + 0x53D9,0x8F96, // + 0x53DB,0x94BE, // + 0x53DF,0x99D5, // + 0x53E1,0x8962, // + 0x53E2,0x9170, // + 0x53E3,0x8CFB, // + 0x53E4,0x8CC3, // + 0x53E5,0x8BE5, // + 0x53E8,0x99D9, // + 0x53E9,0x9240, // + 0x53EA,0x91FC, // + 0x53EB,0x8BA9, // + 0x53EC,0x8FA2, // + 0x53ED,0x99DA, // + 0x53EE,0x99D8, // + 0x53EF,0x89C2, // + 0x53F0,0x91E4, // + 0x53F1,0x8EB6, // + 0x53F2,0x8E6A, // + 0x53F3,0x8945, // + 0x53F6,0x8A90, // + 0x53F7,0x8D86, // + 0x53F8,0x8E69, // + 0x53FA,0x99DB, // + 0x5401,0x99DC, // + 0x5403,0x8B68, // + 0x5404,0x8A65, // + 0x5408,0x8D87, // + 0x5409,0x8B67, // + 0x540A,0x92DD, // + 0x540B,0x8944, // + 0x540C,0x93AF, // + 0x540D,0x96BC, // + 0x540E,0x8D40, // + 0x540F,0x9799, // + 0x5410,0x9366, // + 0x5411,0x8CFC, // + 0x541B,0x8C4E, // + 0x541D,0x99E5, // + 0x541F,0x8BE1, // + 0x5420,0x9669, // + 0x5426,0x94DB, // + 0x5429,0x99E4, // + 0x542B,0x8ADC, // + 0x542C,0x99DF, // + 0x542D,0x99E0, // + 0x542E,0x99E2, // + 0x5436,0x99E3, // + 0x5438,0x8B7A, // + 0x5439,0x9081, // + 0x543B,0x95AB, // + 0x543C,0x99E1, // + 0x543D,0x99DD, // + 0x543E,0x8CE1, // + 0x5440,0x99DE, // + 0x5442,0x9843, // + 0x5446,0x95F0, // + 0x5448,0x92E6, // + 0x5449,0x8CE0, // + 0x544A,0x8D90, // + 0x544E,0x99E6, // + 0x5451,0x93DB, // + 0x545F,0x99EA, // + 0x5468,0x8EFC, // + 0x546A,0x8EF4, // + 0x5470,0x99ED, // + 0x5471,0x99EB, // + 0x5473,0x96A1, // + 0x5475,0x99E8, // + 0x5476,0x99F1, // + 0x5477,0x99EC, // + 0x547B,0x99EF, // + 0x547C,0x8CC4, // + 0x547D,0x96BD, // + 0x5480,0x99F0, // + 0x5484,0x99F2, // + 0x5486,0x99F4, // + 0x548B,0x8DEE, // + 0x548C,0x9861, // + 0x548E,0x99E9, // + 0x548F,0x99E7, // + 0x5490,0x99F3, // + 0x5492,0x99EE, // + 0x54A2,0x99F6, // + 0x54A4,0x9A42, // + 0x54A5,0x99F8, // + 0x54A8,0x99FC, // + 0x54AB,0x9A40, // + 0x54AC,0x99F9, // + 0x54AF,0x9A5D, // + 0x54B2,0x8DE7, // + 0x54B3,0x8A50, // + 0x54B8,0x99F7, // + 0x54BC,0x9A44, // + 0x54BD,0x88F4, // + 0x54BE,0x9A43, // + 0x54C0,0x88A3, // + 0x54C1,0x9569, // + 0x54C2,0x9A41, // + 0x54C4,0x99FA, // + 0x54C7,0x99F5, // + 0x54C8,0x99FB, // + 0x54C9,0x8DC6, // + 0x54D8,0x9A45, // + 0x54E1,0x88F5, // + 0x54E2,0x9A4E, // + 0x54E5,0x9A46, // + 0x54E6,0x9A47, // + 0x54E8,0x8FA3, // + 0x54E9,0x9689, // + 0x54ED,0x9A4C, // + 0x54EE,0x9A4B, // + 0x54F2,0x934E, // + 0x54FA,0x9A4D, // + 0x54FD,0x9A4A, // + 0x5504,0x8953, // + 0x5506,0x8DB4, // + 0x5507,0x904F, // + 0x550F,0x9A48, // + 0x5510,0x9382, // + 0x5514,0x9A49, // + 0x5516,0x88A0, // + 0x552E,0x9A53, // + 0x552F,0x9742, // + 0x5531,0x8FA5, // + 0x5533,0x9A59, // + 0x5538,0x9A58, // + 0x5539,0x9A4F, // + 0x553E,0x91C1, // + 0x5540,0x9A50, // + 0x5544,0x91ED, // + 0x5545,0x9A55, // + 0x5546,0x8FA4, // + 0x554C,0x9A52, // + 0x554F,0x96E2, // + 0x5556,0x9A56, // + 0x5557,0x9A57, // + 0x555C,0x9A54, // + 0x555D,0x9A5A, // + 0x5563,0x9A51, // + 0x557B,0x9A60, // + 0x557C,0x9A65, // + 0x557E,0x9A61, // + 0x5580,0x9A5C, // + 0x5583,0x9A66, // + 0x5584,0x9150, // + 0x5587,0x9A68, // + 0x5589,0x8D41, // + 0x558A,0x9A5E, // + 0x558B,0x929D, // + 0x5598,0x9A62, // + 0x559A,0x8AAB, // + 0x559C,0x8AEC, // + 0x559D,0x8A85, // + 0x559E,0x9A63, // + 0x559F,0x9A5F, // + 0x55A7,0x8C96, // + 0x55A8,0x9A69, // + 0x55A9,0x9A67, // + 0x55AA,0x9172, // + 0x55AB,0x8B69, // + 0x55AC,0x8BAA, // + 0x55AE,0x9A64, // + 0x55B0,0x8BF2, // + 0x55B6,0x8963, // + 0x55C4,0x9A6D, // + 0x55C5,0x9A6B, // + 0x55C7,0x9AA5, // + 0x55D4,0x9A70, // + 0x55DA,0x9A6A, // + 0x55DC,0x9A6E, // + 0x55DF,0x9A6C, // + 0x55E3,0x8E6B, // + 0x55E4,0x9A6F, // + 0x55F7,0x9A72, // + 0x55F9,0x9A77, // + 0x55FD,0x9A75, // + 0x55FE,0x9A74, // + 0x5606,0x9251, // + 0x5609,0x89C3, // + 0x5614,0x9A71, // + 0x5616,0x9A73, // + 0x5617,0x8FA6, // + 0x5618,0x8952, // + 0x561B,0x9A76, // + 0x5629,0x89DC, // + 0x562F,0x9A82, // + 0x5631,0x8FFA, // + 0x5632,0x9A7D, // + 0x5634,0x9A7B, // + 0x5636,0x9A7C, // + 0x5638,0x9A7E, // + 0x5642,0x895C, // + 0x564C,0x9158, // + 0x564E,0x9A78, // + 0x5650,0x9A79, // + 0x565B,0x8A9A, // + 0x5664,0x9A81, // + 0x5668,0x8AED, // + 0x566A,0x9A84, // + 0x566B,0x9A80, // + 0x566C,0x9A83, // + 0x5674,0x95AC, // + 0x5678,0x93D3, // + 0x567A,0x94B6, // + 0x5680,0x9A86, // + 0x5686,0x9A85, // + 0x5687,0x8A64, // + 0x568A,0x9A87, // + 0x568F,0x9A8A, // + 0x5694,0x9A89, // + 0x56A0,0x9A88, // + 0x56A2,0x9458, // + 0x56A5,0x9A8B, // + 0x56AE,0x9A8C, // + 0x56B4,0x9A8E, // + 0x56B6,0x9A8D, // + 0x56BC,0x9A90, // + 0x56C0,0x9A93, // + 0x56C1,0x9A91, // + 0x56C2,0x9A8F, // + 0x56C3,0x9A92, // + 0x56C8,0x9A94, // + 0x56CE,0x9A95, // + 0x56D1,0x9A96, // + 0x56D3,0x9A97, // + 0x56D7,0x9A98, // + 0x56D8,0x9964, // + 0x56DA,0x8EFA, // + 0x56DB,0x8E6C, // + 0x56DE,0x89F1, // + 0x56E0,0x88F6, // + 0x56E3,0x9263, // + 0x56EE,0x9A99, // + 0x56F0,0x8DA2, // + 0x56F2,0x88CD, // + 0x56F3,0x907D, // + 0x56F9,0x9A9A, // + 0x56FA,0x8CC5, // + 0x56FD,0x8D91, // + 0x56FF,0x9A9C, // + 0x5700,0x9A9B, // + 0x5703,0x95DE, // + 0x5704,0x9A9D, // + 0x5708,0x9A9F, // + 0x5709,0x9A9E, // + 0x570B,0x9AA0, // + 0x570D,0x9AA1, // + 0x570F,0x8C97, // + 0x5712,0x8980, // + 0x5713,0x9AA2, // + 0x5716,0x9AA4, // + 0x5718,0x9AA3, // + 0x571C,0x9AA6, // + 0x571F,0x9379, // + 0x5726,0x9AA7, // + 0x5727,0x88B3, // + 0x5728,0x8DDD, // + 0x572D,0x8C5C, // + 0x5730,0x926E, // + 0x5737,0x9AA8, // + 0x5738,0x9AA9, // + 0x573B,0x9AAB, // + 0x5740,0x9AAC, // + 0x5742,0x8DE2, // + 0x5747,0x8BCF, // + 0x574A,0x9656, // + 0x574E,0x9AAA, // + 0x574F,0x9AAD, // + 0x5750,0x8DBF, // + 0x5751,0x8D42, // + 0x5761,0x9AB1, // + 0x5764,0x8DA3, // + 0x5766,0x9252, // + 0x5769,0x9AAE, // + 0x576A,0x92D8, // + 0x577F,0x9AB2, // + 0x5782,0x9082, // + 0x5788,0x9AB0, // + 0x5789,0x9AB3, // + 0x578B,0x8C5E, // + 0x5793,0x9AB4, // + 0x57A0,0x9AB5, // + 0x57A2,0x8D43, // + 0x57A3,0x8A5F, // + 0x57A4,0x9AB7, // + 0x57AA,0x9AB8, // + 0x57B0,0x9AB9, // + 0x57B3,0x9AB6, // + 0x57C0,0x9AAF, // + 0x57C3,0x9ABA, // + 0x57C6,0x9ABB, // + 0x57CB,0x9684, // + 0x57CE,0x8FE9, // + 0x57D2,0x9ABD, // + 0x57D3,0x9ABE, // + 0x57D4,0x9ABC, // + 0x57D6,0x9AC0, // + 0x57DC,0x9457, // + 0x57DF,0x88E6, // + 0x57E0,0x9575, // + 0x57E3,0x9AC1, // + 0x57F4,0x8FFB, // + 0x57F7,0x8EB7, // + 0x57F9,0x947C, // + 0x57FA,0x8AEE, // + 0x57FC,0x8DE9, // + 0x5800,0x9678, // + 0x5802,0x93B0, // + 0x5805,0x8C98, // + 0x5806,0x91CD, // + 0x580A,0x9ABF, // + 0x580B,0x9AC2, // + 0x5815,0x91C2, // + 0x5819,0x9AC3, // + 0x581D,0x9AC4, // + 0x5821,0x9AC6, // + 0x5824,0x92E7, // + 0x582A,0x8AAC, // + 0x582F,0xEA9F, // + 0x5830,0x8981, // + 0x5831,0x95F1, // + 0x5834,0x8FEA, // + 0x5835,0x9367, // + 0x583A,0x8DE4, // + 0x583D,0x9ACC, // + 0x5840,0x95BB, // + 0x5841,0x97DB, // + 0x584A,0x89F2, // + 0x584B,0x9AC8, // + 0x5851,0x9159, // + 0x5852,0x9ACB, // + 0x5854,0x9383, // + 0x5857,0x9368, // + 0x5858,0x9384, // + 0x5859,0x94B7, // + 0x585A,0x92CB, // + 0x585E,0x8DC7, // + 0x5862,0x9AC7, // + 0x5869,0x8996, // + 0x586B,0x9355, // + 0x5870,0x9AC9, // + 0x5872,0x9AC5, // + 0x5875,0x906F, // + 0x5879,0x9ACD, // + 0x587E,0x8F6D, // + 0x5883,0x8BAB, // + 0x5885,0x9ACE, // + 0x5893,0x95E6, // + 0x5897,0x919D, // + 0x589C,0x92C4, // + 0x589F,0x9AD0, // + 0x58A8,0x966E, // + 0x58AB,0x9AD1, // + 0x58AE,0x9AD6, // + 0x58B3,0x95AD, // + 0x58B8,0x9AD5, // + 0x58B9,0x9ACF, // + 0x58BA,0x9AD2, // + 0x58BB,0x9AD4, // + 0x58BE,0x8DA4, // + 0x58C1,0x95C7, // + 0x58C5,0x9AD7, // + 0x58C7,0x9264, // + 0x58CA,0x89F3, // + 0x58CC,0x8FEB, // + 0x58D1,0x9AD9, // + 0x58D3,0x9AD8, // + 0x58D5,0x8D88, // + 0x58D7,0x9ADA, // + 0x58D8,0x9ADC, // + 0x58D9,0x9ADB, // + 0x58DC,0x9ADE, // + 0x58DE,0x9AD3, // + 0x58DF,0x9AE0, // + 0x58E4,0x9ADF, // + 0x58E5,0x9ADD, // + 0x58EB,0x8E6D, // + 0x58EC,0x9070, // + 0x58EE,0x9173, // + 0x58EF,0x9AE1, // + 0x58F0,0x90BA, // + 0x58F1,0x88EB, // + 0x58F2,0x9484, // + 0x58F7,0x92D9, // + 0x58F9,0x9AE3, // + 0x58FA,0x9AE2, // + 0x58FB,0x9AE4, // + 0x58FC,0x9AE5, // + 0x58FD,0x9AE6, // + 0x5902,0x9AE7, // + 0x5909,0x95CF, // + 0x590A,0x9AE8, // + 0x590F,0x89C4, // + 0x5910,0x9AE9, // + 0x5916,0x8A4F, // + 0x5918,0x99C7, // + 0x5919,0x8F67, // + 0x591A,0x91BD, // + 0x591B,0x9AEA, // + 0x591C,0x96E9, // + 0x5922,0x96B2, // + 0x5925,0x9AEC, // + 0x5927,0x91E5, // + 0x5929,0x9356, // + 0x592A,0x91BE, // + 0x592B,0x9576, // + 0x592C,0x9AED, // + 0x592D,0x9AEE, // + 0x592E,0x899B, // + 0x5931,0x8EB8, // + 0x5932,0x9AEF, // + 0x5937,0x88CE, // + 0x5938,0x9AF0, // + 0x593E,0x9AF1, // + 0x5944,0x8982, // + 0x5947,0x8AEF, // + 0x5948,0x93DE, // + 0x5949,0x95F2, // + 0x594E,0x9AF5, // + 0x594F,0x9174, // + 0x5950,0x9AF4, // + 0x5951,0x8C5F, // + 0x5954,0x967A, // + 0x5955,0x9AF3, // + 0x5957,0x9385, // + 0x5958,0x9AF7, // + 0x595A,0x9AF6, // + 0x5960,0x9AF9, // + 0x5962,0x9AF8, // + 0x5965,0x899C, // + 0x5967,0x9AFA, // + 0x5968,0x8FA7, // + 0x5969,0x9AFC, // + 0x596A,0x9244, // + 0x596C,0x9AFB, // + 0x596E,0x95B1, // + 0x5973,0x8F97, // + 0x5974,0x937A, // + 0x5978,0x9B40, // + 0x597D,0x8D44, // + 0x5981,0x9B41, // + 0x5982,0x9440, // + 0x5983,0x94DC, // + 0x5984,0x96CF, // + 0x598A,0x9444, // + 0x598D,0x9B4A, // + 0x5993,0x8B57, // + 0x5996,0x9764, // + 0x5999,0x96AD, // + 0x599B,0x9BAA, // + 0x599D,0x9B42, // + 0x59A3,0x9B45, // + 0x59A5,0x91C3, // + 0x59A8,0x9657, // + 0x59AC,0x9369, // + 0x59B2,0x9B46, // + 0x59B9,0x9685, // + 0x59BB,0x8DC8, // + 0x59BE,0x8FA8, // + 0x59C6,0x9B47, // + 0x59C9,0x8E6F, // + 0x59CB,0x8E6E, // + 0x59D0,0x88B7, // + 0x59D1,0x8CC6, // + 0x59D3,0x90A9, // + 0x59D4,0x88CF, // + 0x59D9,0x9B4B, // + 0x59DA,0x9B4C, // + 0x59DC,0x9B49, // + 0x59E5,0x8957, // + 0x59E6,0x8AAD, // + 0x59E8,0x9B48, // + 0x59EA,0x96C3, // + 0x59EB,0x9550, // + 0x59F6,0x88A6, // + 0x59FB,0x88F7, // + 0x59FF,0x8E70, // + 0x5A01,0x88D0, // + 0x5A03,0x88A1, // + 0x5A09,0x9B51, // + 0x5A11,0x9B4F, // + 0x5A18,0x96BA, // + 0x5A1A,0x9B52, // + 0x5A1C,0x9B50, // + 0x5A1F,0x9B4E, // + 0x5A20,0x9050, // + 0x5A25,0x9B4D, // + 0x5A29,0x95D8, // + 0x5A2F,0x8CE2, // + 0x5A35,0x9B56, // + 0x5A36,0x9B57, // + 0x5A3C,0x8FA9, // + 0x5A40,0x9B53, // + 0x5A41,0x984B, // + 0x5A46,0x946B, // + 0x5A49,0x9B55, // + 0x5A5A,0x8DA5, // + 0x5A62,0x9B58, // + 0x5A66,0x9577, // + 0x5A6A,0x9B59, // + 0x5A6C,0x9B54, // + 0x5A7F,0x96B9, // + 0x5A92,0x947D, // + 0x5A9A,0x9B5A, // + 0x5A9B,0x9551, // + 0x5ABD,0x9B5F, // + 0x5ABE,0x9B5C, // + 0x5AC1,0x89C5, // + 0x5AC2,0x9B5E, // + 0x5AC9,0x8EB9, // + 0x5ACB,0x9B5D, // + 0x5ACC,0x8C99, // + 0x5AD0,0x9B6B, // + 0x5AD6,0x9B64, // + 0x5AD7,0x9B61, // + 0x5AE1,0x9284, // + 0x5AE3,0x9B60, // + 0x5AE6,0x9B62, // + 0x5AE9,0x9B63, // + 0x5AFA,0x9B65, // + 0x5AFB,0x9B66, // + 0x5B09,0x8AF0, // + 0x5B0B,0x9B68, // + 0x5B0C,0x9B67, // + 0x5B16,0x9B69, // + 0x5B22,0x8FEC, // + 0x5B2A,0x9B6C, // + 0x5B2C,0x92DA, // + 0x5B30,0x8964, // + 0x5B32,0x9B6A, // + 0x5B36,0x9B6D, // + 0x5B3E,0x9B6E, // + 0x5B40,0x9B71, // + 0x5B43,0x9B6F, // + 0x5B45,0x9B70, // + 0x5B50,0x8E71, // + 0x5B51,0x9B72, // + 0x5B54,0x8D45, // + 0x5B55,0x9B73, // + 0x5B57,0x8E9A, // + 0x5B58,0x91B6, // + 0x5B5A,0x9B74, // + 0x5B5B,0x9B75, // + 0x5B5C,0x8E79, // + 0x5B5D,0x8D46, // + 0x5B5F,0x96D0, // + 0x5B63,0x8B47, // + 0x5B64,0x8CC7, // + 0x5B65,0x9B76, // + 0x5B66,0x8A77, // + 0x5B69,0x9B77, // + 0x5B6B,0x91B7, // + 0x5B70,0x9B78, // + 0x5B71,0x9BA1, // + 0x5B73,0x9B79, // + 0x5B75,0x9B7A, // + 0x5B78,0x9B7B, // + 0x5B7A,0x9B7D, // + 0x5B80,0x9B7E, // + 0x5B83,0x9B80, // + 0x5B85,0x91EE, // + 0x5B87,0x8946, // + 0x5B88,0x8EE7, // + 0x5B89,0x88C0, // + 0x5B8B,0x9176, // + 0x5B8C,0x8AAE, // + 0x5B8D,0x8EB3, // + 0x5B8F,0x8D47, // + 0x5B95,0x9386, // + 0x5B97,0x8F40, // + 0x5B98,0x8AAF, // + 0x5B99,0x9288, // + 0x5B9A,0x92E8, // + 0x5B9B,0x88B6, // + 0x5B9C,0x8B58, // + 0x5B9D,0x95F3, // + 0x5B9F,0x8EC0, // + 0x5BA2,0x8B71, // + 0x5BA3,0x90E9, // + 0x5BA4,0x8EBA, // + 0x5BA5,0x9747, // + 0x5BA6,0x9B81, // + 0x5BAE,0x8B7B, // + 0x5BB0,0x8DC9, // + 0x5BB3,0x8A51, // + 0x5BB4,0x8983, // + 0x5BB5,0x8FAA, // + 0x5BB6,0x89C6, // + 0x5BB8,0x9B82, // + 0x5BB9,0x9765, // + 0x5BBF,0x8F68, // + 0x5BC2,0x8EE2, // + 0x5BC3,0x9B83, // + 0x5BC4,0x8AF1, // + 0x5BC5,0x93D0, // + 0x5BC6,0x96A7, // + 0x5BC7,0x9B84, // + 0x5BC9,0x9B85, // + 0x5BCC,0x9578, // + 0x5BD0,0x9B87, // + 0x5BD2,0x8AA6, // + 0x5BD3,0x8BF5, // + 0x5BD4,0x9B86, // + 0x5BDB,0x8AB0, // + 0x5BDD,0x9051, // + 0x5BDE,0x9B8B, // + 0x5BDF,0x8E40, // + 0x5BE1,0x89C7, // + 0x5BE2,0x9B8A, // + 0x5BE4,0x9B88, // + 0x5BE5,0x9B8C, // + 0x5BE6,0x9B89, // + 0x5BE7,0x944A, // + 0x5BE8,0x9ECB, // + 0x5BE9,0x9052, // + 0x5BEB,0x9B8D, // + 0x5BEE,0x97BE, // + 0x5BF0,0x9B8E, // + 0x5BF3,0x9B90, // + 0x5BF5,0x929E, // + 0x5BF6,0x9B8F, // + 0x5BF8,0x90A1, // + 0x5BFA,0x8E9B, // + 0x5BFE,0x91CE, // + 0x5BFF,0x8EF5, // + 0x5C01,0x9595, // + 0x5C02,0x90EA, // + 0x5C04,0x8ECB, // + 0x5C05,0x9B91, // + 0x5C06,0x8FAB, // + 0x5C07,0x9B92, // + 0x5C08,0x9B93, // + 0x5C09,0x88D1, // + 0x5C0A,0x91B8, // + 0x5C0B,0x9071, // + 0x5C0D,0x9B94, // + 0x5C0E,0x93B1, // + 0x5C0F,0x8FAC, // + 0x5C11,0x8FAD, // + 0x5C13,0x9B95, // + 0x5C16,0x90EB, // + 0x5C1A,0x8FAE, // + 0x5C20,0x9B96, // + 0x5C22,0x9B97, // + 0x5C24,0x96DE, // + 0x5C28,0x9B98, // + 0x5C2D,0x8BC4, // + 0x5C31,0x8F41, // + 0x5C38,0x9B99, // + 0x5C39,0x9B9A, // + 0x5C3A,0x8EDA, // + 0x5C3B,0x904B, // + 0x5C3C,0x93F2, // + 0x5C3D,0x9073, // + 0x5C3E,0x94F6, // + 0x5C3F,0x9441, // + 0x5C40,0x8BC7, // + 0x5C41,0x9B9B, // + 0x5C45,0x8B8F, // + 0x5C46,0x9B9C, // + 0x5C48,0x8BFC, // + 0x5C4A,0x93CD, // + 0x5C4B,0x89AE, // + 0x5C4D,0x8E72, // + 0x5C4E,0x9B9D, // + 0x5C4F,0x9BA0, // + 0x5C50,0x9B9F, // + 0x5C51,0x8BFB, // + 0x5C53,0x9B9E, // + 0x5C55,0x9357, // + 0x5C5E,0x91AE, // + 0x5C60,0x936A, // + 0x5C61,0x8EC6, // + 0x5C64,0x9177, // + 0x5C65,0x979A, // + 0x5C6C,0x9BA2, // + 0x5C6E,0x9BA3, // + 0x5C6F,0x93D4, // + 0x5C71,0x8E52, // + 0x5C76,0x9BA5, // + 0x5C79,0x9BA6, // + 0x5C8C,0x9BA7, // + 0x5C90,0x8AF2, // + 0x5C91,0x9BA8, // + 0x5C94,0x9BA9, // + 0x5CA1,0x89AA, // + 0x5CA8,0x915A, // + 0x5CA9,0x8AE2, // + 0x5CAB,0x9BAB, // + 0x5CAC,0x96A6, // + 0x5CB1,0x91D0, // + 0x5CB3,0x8A78, // + 0x5CB6,0x9BAD, // + 0x5CB7,0x9BAF, // + 0x5CB8,0x8ADD, // + 0x5CBB,0x9BAC, // + 0x5CBC,0x9BAE, // + 0x5CBE,0x9BB1, // + 0x5CC5,0x9BB0, // + 0x5CC7,0x9BB2, // + 0x5CD9,0x9BB3, // + 0x5CE0,0x93BB, // + 0x5CE1,0x8BAC, // + 0x5CE8,0x89E3, // + 0x5CE9,0x9BB4, // + 0x5CEA,0x9BB9, // + 0x5CED,0x9BB7, // + 0x5CEF,0x95F5, // + 0x5CF0,0x95F4, // + 0x5CF6,0x9387, // + 0x5CFA,0x9BB6, // + 0x5CFB,0x8F73, // + 0x5CFD,0x9BB5, // + 0x5D07,0x9092, // + 0x5D0B,0x9BBA, // + 0x5D0E,0x8DE8, // + 0x5D11,0x9BC0, // + 0x5D14,0x9BC1, // + 0x5D15,0x9BBB, // + 0x5D16,0x8A52, // + 0x5D17,0x9BBC, // + 0x5D18,0x9BC5, // + 0x5D19,0x9BC4, // + 0x5D1A,0x9BC3, // + 0x5D1B,0x9BBF, // + 0x5D1F,0x9BBE, // + 0x5D22,0x9BC2, // + 0x5D29,0x95F6, // + 0x5D4B,0x9BC9, // + 0x5D4C,0x9BC6, // + 0x5D4E,0x9BC8, // + 0x5D50,0x9792, // + 0x5D52,0x9BC7, // + 0x5D5C,0x9BBD, // + 0x5D69,0x9093, // + 0x5D6C,0x9BCA, // + 0x5D6F,0x8DB5, // + 0x5D73,0x9BCB, // + 0x5D76,0x9BCC, // + 0x5D82,0x9BCF, // + 0x5D84,0x9BCE, // + 0x5D87,0x9BCD, // + 0x5D8B,0x9388, // + 0x5D8C,0x9BB8, // + 0x5D90,0x9BD5, // + 0x5D9D,0x9BD1, // + 0x5DA2,0x9BD0, // + 0x5DAC,0x9BD2, // + 0x5DAE,0x9BD3, // + 0x5DB7,0x9BD6, // + 0x5DBA,0x97E4, // + 0x5DBC,0x9BD7, // + 0x5DBD,0x9BD4, // + 0x5DC9,0x9BD8, // + 0x5DCC,0x8ADE, // + 0x5DCD,0x9BD9, // + 0x5DD2,0x9BDB, // + 0x5DD3,0x9BDA, // + 0x5DD6,0x9BDC, // + 0x5DDB,0x9BDD, // + 0x5DDD,0x90EC, // + 0x5DDE,0x8F42, // + 0x5DE1,0x8F84, // + 0x5DE3,0x9183, // + 0x5DE5,0x8D48, // + 0x5DE6,0x8DB6, // + 0x5DE7,0x8D49, // + 0x5DE8,0x8B90, // + 0x5DEB,0x9BDE, // + 0x5DEE,0x8DB7, // + 0x5DF1,0x8CC8, // + 0x5DF2,0x9BDF, // + 0x5DF3,0x96A4, // + 0x5DF4,0x9462, // + 0x5DF5,0x9BE0, // + 0x5DF7,0x8D4A, // + 0x5DFB,0x8AAA, // + 0x5DFD,0x9246, // + 0x5DFE,0x8BD0, // + 0x5E02,0x8E73, // + 0x5E03,0x957A, // + 0x5E06,0x94BF, // + 0x5E0B,0x9BE1, // + 0x5E0C,0x8AF3, // + 0x5E11,0x9BE4, // + 0x5E16,0x929F, // + 0x5E19,0x9BE3, // + 0x5E1A,0x9BE2, // + 0x5E1B,0x9BE5, // + 0x5E1D,0x92E9, // + 0x5E25,0x9083, // + 0x5E2B,0x8E74, // + 0x5E2D,0x90C8, // + 0x5E2F,0x91D1, // + 0x5E30,0x8B41, // + 0x5E33,0x92A0, // + 0x5E36,0x9BE6, // + 0x5E37,0x9BE7, // + 0x5E38,0x8FED, // + 0x5E3D,0x9658, // + 0x5E40,0x9BEA, // + 0x5E43,0x9BE9, // + 0x5E44,0x9BE8, // + 0x5E45,0x959D, // + 0x5E47,0x9BF1, // + 0x5E4C,0x9679, // + 0x5E4E,0x9BEB, // + 0x5E54,0x9BED, // + 0x5E55,0x968B, // + 0x5E57,0x9BEC, // + 0x5E5F,0x9BEE, // + 0x5E61,0x94A6, // + 0x5E62,0x9BEF, // + 0x5E63,0x95BC, // + 0x5E64,0x9BF0, // + 0x5E72,0x8AB1, // + 0x5E73,0x95BD, // + 0x5E74,0x944E, // + 0x5E75,0x9BF2, // + 0x5E76,0x9BF3, // + 0x5E78,0x8D4B, // + 0x5E79,0x8AB2, // + 0x5E7A,0x9BF4, // + 0x5E7B,0x8CB6, // + 0x5E7C,0x9763, // + 0x5E7D,0x9748, // + 0x5E7E,0x8AF4, // + 0x5E7F,0x9BF6, // + 0x5E81,0x92A1, // + 0x5E83,0x8D4C, // + 0x5E84,0x8FAF, // + 0x5E87,0x94DD, // + 0x5E8A,0x8FB0, // + 0x5E8F,0x8F98, // + 0x5E95,0x92EA, // + 0x5E96,0x95F7, // + 0x5E97,0x9358, // + 0x5E9A,0x8D4D, // + 0x5E9C,0x957B, // + 0x5EA0,0x9BF7, // + 0x5EA6,0x9378, // + 0x5EA7,0x8DC0, // + 0x5EAB,0x8CC9, // + 0x5EAD,0x92EB, // + 0x5EB5,0x88C1, // + 0x5EB6,0x8F8E, // + 0x5EB7,0x8D4E, // + 0x5EB8,0x9766, // + 0x5EC1,0x9BF8, // + 0x5EC2,0x9BF9, // + 0x5EC3,0x9470, // + 0x5EC8,0x9BFA, // + 0x5EC9,0x97F5, // + 0x5ECA,0x984C, // + 0x5ECF,0x9BFC, // + 0x5ED0,0x9BFB, // + 0x5ED3,0x8A66, // + 0x5ED6,0x9C40, // + 0x5EDA,0x9C43, // + 0x5EDB,0x9C44, // + 0x5EDD,0x9C42, // + 0x5EDF,0x955F, // + 0x5EE0,0x8FB1, // + 0x5EE1,0x9C46, // + 0x5EE2,0x9C45, // + 0x5EE3,0x9C41, // + 0x5EE8,0x9C47, // + 0x5EE9,0x9C48, // + 0x5EEC,0x9C49, // + 0x5EF0,0x9C4C, // + 0x5EF1,0x9C4A, // + 0x5EF3,0x9C4B, // + 0x5EF4,0x9C4D, // + 0x5EF6,0x8984, // + 0x5EF7,0x92EC, // + 0x5EF8,0x9C4E, // + 0x5EFA,0x8C9A, // + 0x5EFB,0x89F4, // + 0x5EFC,0x9455, // + 0x5EFE,0x9C4F, // + 0x5EFF,0x93F9, // + 0x5F01,0x95D9, // + 0x5F03,0x9C50, // + 0x5F04,0x984D, // + 0x5F09,0x9C51, // + 0x5F0A,0x95BE, // + 0x5F0B,0x9C54, // + 0x5F0C,0x989F, // + 0x5F0D,0x98AF, // + 0x5F0F,0x8EAE, // + 0x5F10,0x93F3, // + 0x5F11,0x9C55, // + 0x5F13,0x8B7C, // + 0x5F14,0x92A2, // + 0x5F15,0x88F8, // + 0x5F16,0x9C56, // + 0x5F17,0x95A4, // + 0x5F18,0x8D4F, // + 0x5F1B,0x926F, // + 0x5F1F,0x92ED, // + 0x5F25,0x96ED, // + 0x5F26,0x8CB7, // + 0x5F27,0x8CCA, // + 0x5F29,0x9C57, // + 0x5F2D,0x9C58, // + 0x5F2F,0x9C5E, // + 0x5F31,0x8EE3, // + 0x5F35,0x92A3, // + 0x5F37,0x8BAD, // + 0x5F38,0x9C59, // + 0x5F3C,0x954A, // + 0x5F3E,0x9265, // + 0x5F41,0x9C5A, // + 0x5F4A,0x8BAE, // + 0x5F4C,0x9C5C, // + 0x5F4E,0x9C5D, // + 0x5F51,0x9C5F, // + 0x5F53,0x9396, // + 0x5F56,0x9C60, // + 0x5F57,0x9C61, // + 0x5F59,0x9C62, // + 0x5F5C,0x9C53, // + 0x5F5D,0x9C52, // + 0x5F61,0x9C63, // + 0x5F62,0x8C60, // + 0x5F66,0x9546, // + 0x5F69,0x8DCA, // + 0x5F6A,0x9556, // + 0x5F6B,0x92A4, // + 0x5F6C,0x956A, // + 0x5F6D,0x9C64, // + 0x5F70,0x8FB2, // + 0x5F71,0x8965, // + 0x5F73,0x9C65, // + 0x5F77,0x9C66, // + 0x5F79,0x96F0, // + 0x5F7C,0x94DE, // + 0x5F7F,0x9C69, // + 0x5F80,0x899D, // + 0x5F81,0x90AA, // + 0x5F82,0x9C68, // + 0x5F83,0x9C67, // + 0x5F84,0x8C61, // + 0x5F85,0x91D2, // + 0x5F87,0x9C6D, // + 0x5F88,0x9C6B, // + 0x5F8A,0x9C6A, // + 0x5F8B,0x97A5, // + 0x5F8C,0x8CE3, // + 0x5F90,0x8F99, // + 0x5F91,0x9C6C, // + 0x5F92,0x936B, // + 0x5F93,0x8F5D, // + 0x5F97,0x93BE, // + 0x5F98,0x9C70, // + 0x5F99,0x9C6F, // + 0x5F9E,0x9C6E, // + 0x5FA0,0x9C71, // + 0x5FA1,0x8CE4, // + 0x5FA8,0x9C72, // + 0x5FA9,0x959C, // + 0x5FAA,0x8F7A, // + 0x5FAD,0x9C73, // + 0x5FAE,0x94F7, // + 0x5FB3,0x93BF, // + 0x5FB4,0x92A5, // + 0x5FB9,0x934F, // + 0x5FBC,0x9C74, // + 0x5FBD,0x8B4A, // + 0x5FC3,0x9053, // + 0x5FC5,0x954B, // + 0x5FCC,0x8AF5, // + 0x5FCD,0x9445, // + 0x5FD6,0x9C75, // + 0x5FD7,0x8E75, // + 0x5FD8,0x9659, // + 0x5FD9,0x965A, // + 0x5FDC,0x899E, // + 0x5FDD,0x9C7A, // + 0x5FE0,0x9289, // + 0x5FE4,0x9C77, // + 0x5FEB,0x89F5, // + 0x5FF0,0x9CAB, // + 0x5FF1,0x9C79, // + 0x5FF5,0x944F, // + 0x5FF8,0x9C78, // + 0x5FFB,0x9C76, // + 0x5FFD,0x8D9A, // + 0x5FFF,0x9C7C, // + 0x600E,0x9C83, // + 0x600F,0x9C89, // + 0x6010,0x9C81, // + 0x6012,0x937B, // + 0x6015,0x9C86, // + 0x6016,0x957C, // + 0x6019,0x9C80, // + 0x601B,0x9C85, // + 0x601C,0x97E5, // + 0x601D,0x8E76, // + 0x6020,0x91D3, // + 0x6021,0x9C7D, // + 0x6025,0x8B7D, // + 0x6026,0x9C88, // + 0x6027,0x90AB, // + 0x6028,0x8985, // + 0x6029,0x9C82, // + 0x602A,0x89F6, // + 0x602B,0x9C87, // + 0x602F,0x8BAF, // + 0x6031,0x9C84, // + 0x603A,0x9C8A, // + 0x6041,0x9C8C, // + 0x6042,0x9C96, // + 0x6043,0x9C94, // + 0x6046,0x9C91, // + 0x604A,0x9C90, // + 0x604B,0x97F6, // + 0x604D,0x9C92, // + 0x6050,0x8BB0, // + 0x6052,0x8D50, // + 0x6055,0x8F9A, // + 0x6059,0x9C99, // + 0x605A,0x9C8B, // + 0x605F,0x9C8F, // + 0x6060,0x9C7E, // + 0x6062,0x89F8, // + 0x6063,0x9C93, // + 0x6064,0x9C95, // + 0x6065,0x9270, // + 0x6068,0x8DA6, // + 0x6069,0x89B6, // + 0x606A,0x9C8D, // + 0x606B,0x9C98, // + 0x606C,0x9C97, // + 0x606D,0x8BB1, // + 0x606F,0x91A7, // + 0x6070,0x8A86, // + 0x6075,0x8C62, // + 0x6077,0x9C8E, // + 0x6081,0x9C9A, // + 0x6083,0x9C9D, // + 0x6084,0x9C9F, // + 0x6089,0x8EBB, // + 0x608B,0x9CA5, // + 0x608C,0x92EE, // + 0x608D,0x9C9B, // + 0x6092,0x9CA3, // + 0x6094,0x89F7, // + 0x6096,0x9CA1, // + 0x6097,0x9CA2, // + 0x609A,0x9C9E, // + 0x609B,0x9CA0, // + 0x609F,0x8CE5, // + 0x60A0,0x9749, // + 0x60A3,0x8AB3, // + 0x60A6,0x8978, // + 0x60A7,0x9CA4, // + 0x60A9,0x9459, // + 0x60AA,0x88AB, // + 0x60B2,0x94DF, // + 0x60B3,0x9C7B, // + 0x60B4,0x9CAA, // + 0x60B5,0x9CAE, // + 0x60B6,0x96E3, // + 0x60B8,0x9CA7, // + 0x60BC,0x9389, // + 0x60BD,0x9CAC, // + 0x60C5,0x8FEE, // + 0x60C6,0x9CAD, // + 0x60C7,0x93D5, // + 0x60D1,0x9866, // + 0x60D3,0x9CA9, // + 0x60D8,0x9CAF, // + 0x60DA,0x8D9B, // + 0x60DC,0x90C9, // + 0x60DF,0x88D2, // + 0x60E0,0x9CA8, // + 0x60E1,0x9CA6, // + 0x60E3,0x9179, // + 0x60E7,0x9C9C, // + 0x60E8,0x8E53, // + 0x60F0,0x91C4, // + 0x60F1,0x9CBB, // + 0x60F3,0x917A, // + 0x60F4,0x9CB6, // + 0x60F6,0x9CB3, // + 0x60F7,0x9CB4, // + 0x60F9,0x8EE4, // + 0x60FA,0x9CB7, // + 0x60FB,0x9CBA, // + 0x6100,0x9CB5, // + 0x6101,0x8F44, // + 0x6103,0x9CB8, // + 0x6106,0x9CB2, // + 0x6108,0x96FA, // + 0x6109,0x96F9, // + 0x610D,0x9CBC, // + 0x610E,0x9CBD, // + 0x610F,0x88D3, // + 0x6115,0x9CB1, // + 0x611A,0x8BF0, // + 0x611B,0x88A4, // + 0x611F,0x8AB4, // + 0x6121,0x9CB9, // + 0x6127,0x9CC1, // + 0x6128,0x9CC0, // + 0x612C,0x9CC5, // + 0x6134,0x9CC6, // + 0x613C,0x9CC4, // + 0x613D,0x9CC7, // + 0x613E,0x9CBF, // + 0x613F,0x9CC3, // + 0x6142,0x9CC8, // + 0x6144,0x9CC9, // + 0x6147,0x9CBE, // + 0x6148,0x8E9C, // + 0x614A,0x9CC2, // + 0x614B,0x91D4, // + 0x614C,0x8D51, // + 0x614D,0x9CB0, // + 0x614E,0x9054, // + 0x6153,0x9CD6, // + 0x6155,0x95E7, // + 0x6158,0x9CCC, // + 0x6159,0x9CCD, // + 0x615A,0x9CCE, // + 0x615D,0x9CD5, // + 0x615F,0x9CD4, // + 0x6162,0x969D, // + 0x6163,0x8AB5, // + 0x6165,0x9CD2, // + 0x6167,0x8C64, // + 0x6168,0x8A53, // + 0x616B,0x9CCF, // + 0x616E,0x97B6, // + 0x616F,0x9CD1, // + 0x6170,0x88D4, // + 0x6171,0x9CD3, // + 0x6173,0x9CCA, // + 0x6174,0x9CD0, // + 0x6175,0x9CD7, // + 0x6176,0x8C63, // + 0x6177,0x9CCB, // + 0x617E,0x977C, // + 0x6182,0x974A, // + 0x6187,0x9CDA, // + 0x618A,0x9CDE, // + 0x618E,0x919E, // + 0x6190,0x97F7, // + 0x6191,0x9CDF, // + 0x6194,0x9CDC, // + 0x6196,0x9CD9, // + 0x6199,0x9CD8, // + 0x619A,0x9CDD, // + 0x61A4,0x95AE, // + 0x61A7,0x93B2, // + 0x61A9,0x8C65, // + 0x61AB,0x9CE0, // + 0x61AC,0x9CDB, // + 0x61AE,0x9CE1, // + 0x61B2,0x8C9B, // + 0x61B6,0x89AF, // + 0x61BA,0x9CE9, // + 0x61BE,0x8AB6, // + 0x61C3,0x9CE7, // + 0x61C6,0x9CE8, // + 0x61C7,0x8DA7, // + 0x61C8,0x9CE6, // + 0x61C9,0x9CE4, // + 0x61CA,0x9CE3, // + 0x61CB,0x9CEA, // + 0x61CC,0x9CE2, // + 0x61CD,0x9CEC, // + 0x61D0,0x89F9, // + 0x61E3,0x9CEE, // + 0x61E6,0x9CED, // + 0x61F2,0x92A6, // + 0x61F4,0x9CF1, // + 0x61F6,0x9CEF, // + 0x61F7,0x9CE5, // + 0x61F8,0x8C9C, // + 0x61FA,0x9CF0, // + 0x61FC,0x9CF4, // + 0x61FD,0x9CF3, // + 0x61FE,0x9CF5, // + 0x61FF,0x9CF2, // + 0x6200,0x9CF6, // + 0x6208,0x9CF7, // + 0x6209,0x9CF8, // + 0x620A,0x95E8, // + 0x620C,0x9CFA, // + 0x620D,0x9CF9, // + 0x620E,0x8F5E, // + 0x6210,0x90AC, // + 0x6211,0x89E4, // + 0x6212,0x89FA, // + 0x6214,0x9CFB, // + 0x6216,0x88BD, // + 0x621A,0x90CA, // + 0x621B,0x9CFC, // + 0x621D,0xE6C1, // + 0x621E,0x9D40, // + 0x621F,0x8C81, // + 0x6221,0x9D41, // + 0x6226,0x90ED, // + 0x622A,0x9D42, // + 0x622E,0x9D43, // + 0x622F,0x8B59, // + 0x6230,0x9D44, // + 0x6232,0x9D45, // + 0x6233,0x9D46, // + 0x6234,0x91D5, // + 0x6238,0x8CCB, // + 0x623B,0x96DF, // + 0x6240,0x8F8A, // + 0x6241,0x9D47, // + 0x6247,0x90EE, // + 0x6248,0xE7BB, // + 0x6249,0x94E0, // + 0x624B,0x8EE8, // + 0x624D,0x8DCB, // + 0x624E,0x9D48, // + 0x6253,0x91C5, // + 0x6255,0x95A5, // + 0x6258,0x91EF, // + 0x625B,0x9D4B, // + 0x625E,0x9D49, // + 0x6260,0x9D4C, // + 0x6263,0x9D4A, // + 0x6268,0x9D4D, // + 0x626E,0x95AF, // + 0x6271,0x88B5, // + 0x6276,0x957D, // + 0x6279,0x94E1, // + 0x627C,0x9D4E, // + 0x627E,0x9D51, // + 0x627F,0x8FB3, // + 0x6280,0x8B5A, // + 0x6282,0x9D4F, // + 0x6283,0x9D56, // + 0x6284,0x8FB4, // + 0x6289,0x9D50, // + 0x628A,0x9463, // + 0x6291,0x977D, // + 0x6292,0x9D52, // + 0x6293,0x9D53, // + 0x6294,0x9D57, // + 0x6295,0x938A, // + 0x6296,0x9D54, // + 0x6297,0x8D52, // + 0x6298,0x90DC, // + 0x629B,0x9D65, // + 0x629C,0x94B2, // + 0x629E,0x91F0, // + 0x62AB,0x94E2, // + 0x62AC,0x9DAB, // + 0x62B1,0x95F8, // + 0x62B5,0x92EF, // + 0x62B9,0x9695, // + 0x62BB,0x9D5A, // + 0x62BC,0x899F, // + 0x62BD,0x928A, // + 0x62C2,0x9D63, // + 0x62C5,0x9253, // + 0x62C6,0x9D5D, // + 0x62C7,0x9D64, // + 0x62C8,0x9D5F, // + 0x62C9,0x9D66, // + 0x62CA,0x9D62, // + 0x62CC,0x9D61, // + 0x62CD,0x948F, // + 0x62D0,0x89FB, // + 0x62D1,0x9D59, // + 0x62D2,0x8B91, // + 0x62D3,0x91F1, // + 0x62D4,0x9D55, // + 0x62D7,0x9D58, // + 0x62D8,0x8D53, // + 0x62D9,0x90D9, // + 0x62DB,0x8FB5, // + 0x62DC,0x9D60, // + 0x62DD,0x9471, // + 0x62E0,0x8B92, // + 0x62E1,0x8A67, // + 0x62EC,0x8A87, // + 0x62ED,0x9040, // + 0x62EE,0x9D68, // + 0x62EF,0x9D6D, // + 0x62F1,0x9D69, // + 0x62F3,0x8C9D, // + 0x62F5,0x9D6E, // + 0x62F6,0x8E41, // + 0x62F7,0x8D89, // + 0x62FE,0x8F45, // + 0x62FF,0x9D5C, // + 0x6301,0x8E9D, // + 0x6302,0x9D6B, // + 0x6307,0x8E77, // + 0x6308,0x9D6C, // + 0x6309,0x88C2, // + 0x630C,0x9D67, // + 0x6311,0x92A7, // + 0x6319,0x8B93, // + 0x631F,0x8BB2, // + 0x6327,0x9D6A, // + 0x6328,0x88A5, // + 0x632B,0x8DC1, // + 0x632F,0x9055, // + 0x633A,0x92F0, // + 0x633D,0x94D2, // + 0x633E,0x9D70, // + 0x633F,0x917D, // + 0x6349,0x91A8, // + 0x634C,0x8E4A, // + 0x634D,0x9D71, // + 0x634F,0x9D73, // + 0x6350,0x9D6F, // + 0x6355,0x95DF, // + 0x6357,0x92BB, // + 0x635C,0x917B, // + 0x6367,0x95F9, // + 0x6368,0x8ECC, // + 0x6369,0x9D80, // + 0x636B,0x9D7E, // + 0x636E,0x9098, // + 0x6372,0x8C9E, // + 0x6376,0x9D78, // + 0x6377,0x8FB7, // + 0x637A,0x93E6, // + 0x637B,0x9450, // + 0x6380,0x9D76, // + 0x6383,0x917C, // + 0x6388,0x8EF6, // + 0x6389,0x9D7B, // + 0x638C,0x8FB6, // + 0x638E,0x9D75, // + 0x638F,0x9D7A, // + 0x6392,0x9472, // + 0x6396,0x9D74, // + 0x6398,0x8C40, // + 0x639B,0x8A7C, // + 0x639F,0x9D7C, // + 0x63A0,0x97A9, // + 0x63A1,0x8DCC, // + 0x63A2,0x9254, // + 0x63A3,0x9D79, // + 0x63A5,0x90DA, // + 0x63A7,0x8D54, // + 0x63A8,0x9084, // + 0x63A9,0x8986, // + 0x63AB,0x9D77, // + 0x63AC,0x8B64, // + 0x63B2,0x8C66, // + 0x63B4,0x92CD, // + 0x63B5,0x9D7D, // + 0x63BB,0x917E, // + 0x63BE,0x9D81, // + 0x63C0,0x9D83, // + 0x63C3,0x91B5, // + 0x63C4,0x9D89, // + 0x63C6,0x9D84, // + 0x63C9,0x9D86, // + 0x63CF,0x9560, // + 0x63D0,0x92F1, // + 0x63D2,0x9D87, // + 0x63D6,0x974B, // + 0x63DA,0x9767, // + 0x63DB,0x8AB7, // + 0x63E1,0x88AC, // + 0x63E3,0x9D85, // + 0x63E9,0x9D82, // + 0x63EE,0x8AF6, // + 0x63F4,0x8987, // + 0x63F6,0x9D88, // + 0x63FA,0x9768, // + 0x6406,0x9D8C, // + 0x640D,0x91B9, // + 0x640F,0x9D93, // + 0x6413,0x9D8D, // + 0x6416,0x9D8A, // + 0x6417,0x9D91, // + 0x641C,0x9D72, // + 0x6426,0x9D8E, // + 0x6428,0x9D92, // + 0x642C,0x94C0, // + 0x642D,0x938B, // + 0x6434,0x9D8B, // + 0x6436,0x9D8F, // + 0x643A,0x8C67, // + 0x643E,0x8DEF, // + 0x6442,0x90DB, // + 0x644E,0x9D97, // + 0x6458,0x9345, // + 0x6467,0x9D94, // + 0x6469,0x9680, // + 0x646F,0x9D95, // + 0x6476,0x9D96, // + 0x6478,0x96CC, // + 0x647A,0x90A0, // + 0x6483,0x8C82, // + 0x6488,0x9D9D, // + 0x6492,0x8E54, // + 0x6493,0x9D9A, // + 0x6495,0x9D99, // + 0x649A,0x9451, // + 0x649E,0x93B3, // + 0x64A4,0x9350, // + 0x64A5,0x9D9B, // + 0x64A9,0x9D9C, // + 0x64AB,0x958F, // + 0x64AD,0x9464, // + 0x64AE,0x8E42, // + 0x64B0,0x90EF, // + 0x64B2,0x966F, // + 0x64B9,0x8A68, // + 0x64BB,0x9DA3, // + 0x64BC,0x9D9E, // + 0x64C1,0x9769, // + 0x64C2,0x9DA5, // + 0x64C5,0x9DA1, // + 0x64C7,0x9DA2, // + 0x64CD,0x9180, // + 0x64D2,0x9DA0, // + 0x64D4,0x9D5E, // + 0x64D8,0x9DA4, // + 0x64DA,0x9D9F, // + 0x64E0,0x9DA9, // + 0x64E1,0x9DAA, // + 0x64E2,0x9346, // + 0x64E3,0x9DAC, // + 0x64E6,0x8E43, // + 0x64E7,0x9DA7, // + 0x64EF,0x9DAD, // + 0x64F1,0x9DA6, // + 0x64F2,0x9DB1, // + 0x64F4,0x9DB0, // + 0x64F6,0x9DAF, // + 0x64FA,0x9DB2, // + 0x64FD,0x9DB4, // + 0x64FE,0x8FEF, // + 0x6500,0x9DB3, // + 0x6505,0x9DB7, // + 0x6518,0x9DB5, // + 0x651C,0x9DB6, // + 0x651D,0x9D90, // + 0x6523,0x9DB9, // + 0x6524,0x9DB8, // + 0x652A,0x9D98, // + 0x652B,0x9DBA, // + 0x652C,0x9DAE, // + 0x652F,0x8E78, // + 0x6534,0x9DBB, // + 0x6535,0x9DBC, // + 0x6536,0x9DBE, // + 0x6537,0x9DBD, // + 0x6538,0x9DBF, // + 0x6539,0x89FC, // + 0x653B,0x8D55, // + 0x653E,0x95FA, // + 0x653F,0x90AD, // + 0x6545,0x8CCC, // + 0x6548,0x9DC1, // + 0x654D,0x9DC4, // + 0x654F,0x9571, // + 0x6551,0x8B7E, // + 0x6555,0x9DC3, // + 0x6556,0x9DC2, // + 0x6557,0x9473, // + 0x6558,0x9DC5, // + 0x6559,0x8BB3, // + 0x655D,0x9DC7, // + 0x655E,0x9DC6, // + 0x6562,0x8AB8, // + 0x6563,0x8E55, // + 0x6566,0x93D6, // + 0x656C,0x8C68, // + 0x6570,0x9094, // + 0x6572,0x9DC8, // + 0x6574,0x90AE, // + 0x6575,0x9347, // + 0x6577,0x957E, // + 0x6578,0x9DC9, // + 0x6582,0x9DCA, // + 0x6583,0x9DCB, // + 0x6587,0x95B6, // + 0x6588,0x9B7C, // + 0x6589,0x90C4, // + 0x658C,0x956B, // + 0x658E,0x8DD6, // + 0x6590,0x94E3, // + 0x6591,0x94C1, // + 0x6597,0x936C, // + 0x6599,0x97BF, // + 0x659B,0x9DCD, // + 0x659C,0x8ECE, // + 0x659F,0x9DCE, // + 0x65A1,0x88B4, // + 0x65A4,0x8BD2, // + 0x65A5,0x90CB, // + 0x65A7,0x9580, // + 0x65AB,0x9DCF, // + 0x65AC,0x8E61, // + 0x65AD,0x9266, // + 0x65AF,0x8E7A, // + 0x65B0,0x9056, // + 0x65B7,0x9DD0, // + 0x65B9,0x95FB, // + 0x65BC,0x8997, // + 0x65BD,0x8E7B, // + 0x65C1,0x9DD3, // + 0x65C3,0x9DD1, // + 0x65C4,0x9DD4, // + 0x65C5,0x97B7, // + 0x65C6,0x9DD2, // + 0x65CB,0x90F9, // + 0x65CC,0x9DD5, // + 0x65CF,0x91B0, // + 0x65D2,0x9DD6, // + 0x65D7,0x8AF8, // + 0x65D9,0x9DD8, // + 0x65DB,0x9DD7, // + 0x65E0,0x9DD9, // + 0x65E1,0x9DDA, // + 0x65E2,0x8AF9, // + 0x65E5,0x93FA, // + 0x65E6,0x9255, // + 0x65E7,0x8B8C, // + 0x65E8,0x8E7C, // + 0x65E9,0x9181, // + 0x65EC,0x8F7B, // + 0x65ED,0x88AE, // + 0x65F1,0x9DDB, // + 0x65FA,0x89A0, // + 0x65FB,0x9DDF, // + 0x6602,0x8D56, // + 0x6603,0x9DDE, // + 0x6606,0x8DA9, // + 0x6607,0x8FB8, // + 0x660A,0x9DDD, // + 0x660C,0x8FB9, // + 0x660E,0x96BE, // + 0x660F,0x8DA8, // + 0x6613,0x88D5, // + 0x6614,0x90CC, // + 0x661C,0x9DE4, // + 0x661F,0x90AF, // + 0x6620,0x8966, // + 0x6625,0x8F74, // + 0x6627,0x9686, // + 0x6628,0x8DF0, // + 0x662D,0x8FBA, // + 0x662F,0x90A5, // + 0x6634,0x9DE3, // + 0x6635,0x9DE1, // + 0x6636,0x9DE2, // + 0x663C,0x928B, // + 0x663F,0x9E45, // + 0x6641,0x9DE8, // + 0x6642,0x8E9E, // + 0x6643,0x8D57, // + 0x6644,0x9DE6, // + 0x6649,0x9DE7, // + 0x664B,0x9057, // + 0x664F,0x9DE5, // + 0x6652,0x8E4E, // + 0x665D,0x9DEA, // + 0x665E,0x9DE9, // + 0x665F,0x9DEE, // + 0x6662,0x9DEF, // + 0x6664,0x9DEB, // + 0x6666,0x8A41, // + 0x6667,0x9DEC, // + 0x6668,0x9DED, // + 0x6669,0x94D3, // + 0x666E,0x9581, // + 0x666F,0x8C69, // + 0x6670,0x9DF0, // + 0x6674,0x90B0, // + 0x6676,0x8FBB, // + 0x667A,0x9271, // + 0x6681,0x8BC5, // + 0x6683,0x9DF1, // + 0x6684,0x9DF5, // + 0x6687,0x89C9, // + 0x6688,0x9DF2, // + 0x6689,0x9DF4, // + 0x668E,0x9DF3, // + 0x6691,0x8F8B, // + 0x6696,0x9267, // + 0x6697,0x88C3, // + 0x6698,0x9DF6, // + 0x669D,0x9DF7, // + 0x66A2,0x92A8, // + 0x66A6,0x97EF, // + 0x66AB,0x8E62, // + 0x66AE,0x95E9, // + 0x66B4,0x965C, // + 0x66B8,0x9E41, // + 0x66B9,0x9DF9, // + 0x66BC,0x9DFC, // + 0x66BE,0x9DFB, // + 0x66C1,0x9DF8, // + 0x66C4,0x9E40, // + 0x66C7,0x93DC, // + 0x66C9,0x9DFA, // + 0x66D6,0x9E42, // + 0x66D9,0x8F8C, // + 0x66DA,0x9E43, // + 0x66DC,0x976A, // + 0x66DD,0x9498, // + 0x66E0,0x9E44, // + 0x66E6,0x9E46, // + 0x66E9,0x9E47, // + 0x66F0,0x9E48, // + 0x66F2,0x8BC8, // + 0x66F3,0x8967, // + 0x66F4,0x8D58, // + 0x66F5,0x9E49, // + 0x66F7,0x9E4A, // + 0x66F8,0x8F91, // + 0x66F9,0x9182, // + 0x66FC,0x99D6, // + 0x66FD,0x915D, // + 0x66FE,0x915C, // + 0x66FF,0x91D6, // + 0x6700,0x8DC5, // + 0x6703,0x98F0, // + 0x6708,0x8C8E, // + 0x6709,0x974C, // + 0x670B,0x95FC, // + 0x670D,0x959E, // + 0x670F,0x9E4B, // + 0x6714,0x8DF1, // + 0x6715,0x92BD, // + 0x6716,0x9E4C, // + 0x6717,0x984E, // + 0x671B,0x965D, // + 0x671D,0x92A9, // + 0x671E,0x9E4D, // + 0x671F,0x8AFA, // + 0x6726,0x9E4E, // + 0x6727,0x9E4F, // + 0x6728,0x96D8, // + 0x672A,0x96A2, // + 0x672B,0x9696, // + 0x672C,0x967B, // + 0x672D,0x8E44, // + 0x672E,0x9E51, // + 0x6731,0x8EE9, // + 0x6734,0x9670, // + 0x6736,0x9E53, // + 0x6737,0x9E56, // + 0x6738,0x9E55, // + 0x673A,0x8AF7, // + 0x673D,0x8B80, // + 0x673F,0x9E52, // + 0x6741,0x9E54, // + 0x6746,0x9E57, // + 0x6749,0x9099, // + 0x674E,0x979B, // + 0x674F,0x88C7, // + 0x6750,0x8DDE, // + 0x6751,0x91BA, // + 0x6753,0x8EDB, // + 0x6756,0x8FF1, // + 0x6759,0x9E5A, // + 0x675C,0x936D, // + 0x675E,0x9E58, // + 0x675F,0x91A9, // + 0x6760,0x9E59, // + 0x6761,0x8FF0, // + 0x6762,0x96DB, // + 0x6764,0x9E5C, // + 0x6765,0x9788, // + 0x676A,0x9E61, // + 0x676D,0x8D59, // + 0x676F,0x9474, // + 0x6770,0x9E5E, // + 0x6771,0x938C, // + 0x6772,0x9DDC, // + 0x6773,0x9DE0, // + 0x6775,0x8B6E, // + 0x6777,0x9466, // + 0x677C,0x9E60, // + 0x677E,0x8FBC, // + 0x677F,0x94C2, // + 0x6785,0x9E66, // + 0x6787,0x94F8, // + 0x6789,0x9E5D, // + 0x678B,0x9E63, // + 0x678C,0x9E62, // + 0x6790,0x90CD, // + 0x6795,0x968D, // + 0x6797,0x97D1, // + 0x679A,0x9687, // + 0x679C,0x89CA, // + 0x679D,0x8E7D, // + 0x67A0,0x9867, // + 0x67A1,0x9E65, // + 0x67A2,0x9095, // + 0x67A6,0x9E64, // + 0x67A9,0x9E5F, // + 0x67AF,0x8CCD, // + 0x67B3,0x9E6B, // + 0x67B4,0x9E69, // + 0x67B6,0x89CB, // + 0x67B7,0x9E67, // + 0x67B8,0x9E6D, // + 0x67B9,0x9E73, // + 0x67C1,0x91C6, // + 0x67C4,0x95BF, // + 0x67C6,0x9E75, // + 0x67CA,0x9541, // + 0x67CE,0x9E74, // + 0x67CF,0x9490, // + 0x67D0,0x965E, // + 0x67D1,0x8AB9, // + 0x67D3,0x90F5, // + 0x67D4,0x8F5F, // + 0x67D8,0x92D1, // + 0x67DA,0x974D, // + 0x67DD,0x9E70, // + 0x67DE,0x9E6F, // + 0x67E2,0x9E71, // + 0x67E4,0x9E6E, // + 0x67E7,0x9E76, // + 0x67E9,0x9E6C, // + 0x67EC,0x9E6A, // + 0x67EE,0x9E72, // + 0x67EF,0x9E68, // + 0x67F1,0x928C, // + 0x67F3,0x96F6, // + 0x67F4,0x8EC4, // + 0x67F5,0x8DF2, // + 0x67FB,0x8DB8, // + 0x67FE,0x968F, // + 0x67FF,0x8A60, // + 0x6802,0x92CC, // + 0x6803,0x93C8, // + 0x6804,0x8968, // + 0x6813,0x90F0, // + 0x6816,0x90B2, // + 0x6817,0x8C49, // + 0x681E,0x9E78, // + 0x6821,0x8D5A, // + 0x6822,0x8A9C, // + 0x6829,0x9E7A, // + 0x682A,0x8A94, // + 0x682B,0x9E81, // + 0x6832,0x9E7D, // + 0x6834,0x90F1, // + 0x6838,0x8A6A, // + 0x6839,0x8DAA, // + 0x683C,0x8A69, // + 0x683D,0x8DCD, // + 0x6840,0x9E7B, // + 0x6841,0x8C85, // + 0x6842,0x8C6A, // + 0x6843,0x938D, // + 0x6846,0x9E79, // + 0x6848,0x88C4, // + 0x684D,0x9E7C, // + 0x684E,0x9E7E, // + 0x6850,0x8BCB, // + 0x6851,0x8C4B, // + 0x6853,0x8ABA, // + 0x6854,0x8B6A, // + 0x6859,0x9E82, // + 0x685C,0x8DF7, // + 0x685D,0x9691, // + 0x685F,0x8E56, // + 0x6863,0x9E83, // + 0x6867,0x954F, // + 0x6874,0x9E8F, // + 0x6876,0x89B1, // + 0x6877,0x9E84, // + 0x687E,0x9E95, // + 0x687F,0x9E85, // + 0x6881,0x97C0, // + 0x6883,0x9E8C, // + 0x6885,0x947E, // + 0x688D,0x9E94, // + 0x688F,0x9E87, // + 0x6893,0x88B2, // + 0x6894,0x9E89, // + 0x689B,0x9E8B, // + 0x689D,0x9E8A, // + 0x689F,0x9E86, // + 0x68A0,0x9E91, // + 0x68A2,0x8FBD, // + 0x68A6,0x9AEB, // + 0x68A7,0x8CE6, // + 0x68A8,0x979C, // + 0x68AD,0x9E88, // + 0x68AF,0x92F2, // + 0x68B0,0x8A42, // + 0x68B1,0x8DAB, // + 0x68B3,0x9E80, // + 0x68B5,0x9E90, // + 0x68B6,0x8A81, // + 0x68B9,0x9E8E, // + 0x68BA,0x9E92, // + 0x68BC,0x938E, // + 0x68C4,0x8AFC, // + 0x68C6,0x9EB0, // + 0x68C9,0x96C7, // + 0x68CA,0x9E97, // + 0x68CB,0x8AFB, // + 0x68CD,0x9E9E, // + 0x68D2,0x965F, // + 0x68D4,0x9E9F, // + 0x68D5,0x9EA1, // + 0x68D7,0x9EA5, // + 0x68D8,0x9E99, // + 0x68DA,0x9249, // + 0x68DF,0x938F, // + 0x68E0,0x9EA9, // + 0x68E1,0x9E9C, // + 0x68E3,0x9EA6, // + 0x68E7,0x9EA0, // + 0x68EE,0x9058, // + 0x68EF,0x9EAA, // + 0x68F2,0x90B1, // + 0x68F9,0x9EA8, // + 0x68FA,0x8ABB, // + 0x6900,0x986F, // + 0x6901,0x9E96, // + 0x6904,0x9EA4, // + 0x6905,0x88D6, // + 0x6908,0x9E98, // + 0x690B,0x96B8, // + 0x690C,0x9E9D, // + 0x690D,0x9041, // + 0x690E,0x92C5, // + 0x690F,0x9E93, // + 0x6912,0x9EA3, // + 0x6919,0x909A, // + 0x691A,0x9EAD, // + 0x691B,0x8A91, // + 0x691C,0x8C9F, // + 0x6921,0x9EAF, // + 0x6922,0x9E9A, // + 0x6923,0x9EAE, // + 0x6925,0x9EA7, // + 0x6926,0x9E9B, // + 0x6928,0x9EAB, // + 0x692A,0x9EAC, // + 0x6930,0x9EBD, // + 0x6934,0x93CC, // + 0x6936,0x9EA2, // + 0x6939,0x9EB9, // + 0x693D,0x9EBB, // + 0x693F,0x92D6, // + 0x694A,0x976B, // + 0x6953,0x9596, // + 0x6954,0x9EB6, // + 0x6955,0x91C8, // + 0x6959,0x9EBC, // + 0x695A,0x915E, // + 0x695C,0x9EB3, // + 0x695D,0x9EC0, // + 0x695E,0x9EBF, // + 0x6960,0x93ED, // + 0x6961,0x9EBE, // + 0x6962,0x93E8, // + 0x696A,0x9EC2, // + 0x696B,0x9EB5, // + 0x696D,0x8BC6, // + 0x696E,0x9EB8, // + 0x696F,0x8F7C, // + 0x6973,0x9480, // + 0x6974,0x9EBA, // + 0x6975,0x8BC9, // + 0x6977,0x9EB2, // + 0x6978,0x9EB4, // + 0x6979,0x9EB1, // + 0x697C,0x984F, // + 0x697D,0x8A79, // + 0x697E,0x9EB7, // + 0x6981,0x9EC1, // + 0x6982,0x8A54, // + 0x698A,0x8DE5, // + 0x698E,0x897C, // + 0x6991,0x9ED2, // + 0x6994,0x9850, // + 0x6995,0x9ED5, // + 0x699B,0x9059, // + 0x699C,0x9ED4, // + 0x69A0,0x9ED3, // + 0x69A7,0x9ED0, // + 0x69AE,0x9EC4, // + 0x69B1,0x9EE1, // + 0x69B2,0x9EC3, // + 0x69B4,0x9ED6, // + 0x69BB,0x9ECE, // + 0x69BE,0x9EC9, // + 0x69BF,0x9EC6, // + 0x69C1,0x9EC7, // + 0x69C3,0x9ECF, // + 0x69C7,0xEAA0, // + 0x69CA,0x9ECC, // + 0x69CB,0x8D5C, // + 0x69CC,0x92C6, // + 0x69CD,0x9184, // + 0x69CE,0x9ECA, // + 0x69D0,0x9EC5, // + 0x69D3,0x9EC8, // + 0x69D8,0x976C, // + 0x69D9,0x968A, // + 0x69DD,0x9ECD, // + 0x69DE,0x9ED7, // + 0x69E7,0x9EDF, // + 0x69E8,0x9ED8, // + 0x69EB,0x9EE5, // + 0x69ED,0x9EE3, // + 0x69F2,0x9EDE, // + 0x69F9,0x9EDD, // + 0x69FB,0x92CE, // + 0x69FD,0x9185, // + 0x69FF,0x9EDB, // + 0x6A02,0x9ED9, // + 0x6A05,0x9EE0, // + 0x6A0A,0x9EE6, // + 0x6A0B,0x94F3, // + 0x6A0C,0x9EEC, // + 0x6A12,0x9EE7, // + 0x6A13,0x9EEA, // + 0x6A14,0x9EE4, // + 0x6A17,0x9294, // + 0x6A19,0x9557, // + 0x6A1B,0x9EDA, // + 0x6A1E,0x9EE2, // + 0x6A1F,0x8FBE, // + 0x6A21,0x96CD, // + 0x6A22,0x9EF6, // + 0x6A23,0x9EE9, // + 0x6A29,0x8CA0, // + 0x6A2A,0x89A1, // + 0x6A2B,0x8A7E, // + 0x6A2E,0x9ED1, // + 0x6A35,0x8FBF, // + 0x6A36,0x9EEE, // + 0x6A38,0x9EF5, // + 0x6A39,0x8EF7, // + 0x6A3A,0x8A92, // + 0x6A3D,0x924D, // + 0x6A44,0x9EEB, // + 0x6A47,0x9EF0, // + 0x6A48,0x9EF4, // + 0x6A4B,0x8BB4, // + 0x6A58,0x8B6B, // + 0x6A59,0x9EF2, // + 0x6A5F,0x8B40, // + 0x6A61,0x93C9, // + 0x6A62,0x9EF1, // + 0x6A66,0x9EF3, // + 0x6A72,0x9EED, // + 0x6A78,0x9EEF, // + 0x6A7F,0x8A80, // + 0x6A80,0x9268, // + 0x6A84,0x9EFA, // + 0x6A8D,0x9EF8, // + 0x6A8E,0x8CE7, // + 0x6A90,0x9EF7, // + 0x6A97,0x9F40, // + 0x6A9C,0x9E77, // + 0x6AA0,0x9EF9, // + 0x6AA2,0x9EFB, // + 0x6AA3,0x9EFC, // + 0x6AAA,0x9F4B, // + 0x6AAC,0x9F47, // + 0x6AAE,0x9E8D, // + 0x6AB3,0x9F46, // + 0x6AB8,0x9F45, // + 0x6ABB,0x9F42, // + 0x6AC1,0x9EE8, // + 0x6AC2,0x9F44, // + 0x6AC3,0x9F43, // + 0x6AD1,0x9F49, // + 0x6AD3,0x9845, // + 0x6ADA,0x9F4C, // + 0x6ADB,0x8BF9, // + 0x6ADE,0x9F48, // + 0x6ADF,0x9F4A, // + 0x6AE8,0x94A5, // + 0x6AEA,0x9F4D, // + 0x6AFA,0x9F51, // + 0x6AFB,0x9F4E, // + 0x6B04,0x9793, // + 0x6B05,0x9F4F, // + 0x6B0A,0x9EDC, // + 0x6B12,0x9F52, // + 0x6B16,0x9F53, // + 0x6B1D,0x8954, // + 0x6B1F,0x9F55, // + 0x6B20,0x8C87, // + 0x6B21,0x8E9F, // + 0x6B23,0x8BD3, // + 0x6B27,0x89A2, // + 0x6B32,0x977E, // + 0x6B37,0x9F57, // + 0x6B38,0x9F56, // + 0x6B39,0x9F59, // + 0x6B3A,0x8B5C, // + 0x6B3D,0x8BD4, // + 0x6B3E,0x8ABC, // + 0x6B43,0x9F5C, // + 0x6B49,0x9F5D, // + 0x6B4C,0x89CC, // + 0x6B4E,0x9256, // + 0x6B50,0x9F5E, // + 0x6B53,0x8ABD, // + 0x6B54,0x9F60, // + 0x6B59,0x9F5F, // + 0x6B5B,0x9F61, // + 0x6B5F,0x9F62, // + 0x6B61,0x9F63, // + 0x6B62,0x8E7E, // + 0x6B63,0x90B3, // + 0x6B64,0x8D9F, // + 0x6B66,0x9590, // + 0x6B69,0x95E0, // + 0x6B6A,0x9863, // + 0x6B6F,0x8E95, // + 0x6B73,0x8DCE, // + 0x6B74,0x97F0, // + 0x6B78,0x9F64, // + 0x6B79,0x9F65, // + 0x6B7B,0x8E80, // + 0x6B7F,0x9F66, // + 0x6B80,0x9F67, // + 0x6B83,0x9F69, // + 0x6B84,0x9F68, // + 0x6B86,0x9677, // + 0x6B89,0x8F7D, // + 0x6B8A,0x8EEA, // + 0x6B8B,0x8E63, // + 0x6B8D,0x9F6A, // + 0x6B95,0x9F6C, // + 0x6B96,0x9042, // + 0x6B98,0x9F6B, // + 0x6B9E,0x9F6D, // + 0x6BA4,0x9F6E, // + 0x6BAA,0x9F6F, // + 0x6BAB,0x9F70, // + 0x6BAF,0x9F71, // + 0x6BB1,0x9F73, // + 0x6BB2,0x9F72, // + 0x6BB3,0x9F74, // + 0x6BB4,0x89A3, // + 0x6BB5,0x9269, // + 0x6BB7,0x9F75, // + 0x6BBA,0x8E45, // + 0x6BBB,0x8A6B, // + 0x6BBC,0x9F76, // + 0x6BBF,0x9361, // + 0x6BC0,0x9ACA, // + 0x6BC5,0x8B42, // + 0x6BC6,0x9F77, // + 0x6BCB,0x9F78, // + 0x6BCD,0x95EA, // + 0x6BCE,0x9688, // + 0x6BD2,0x93C5, // + 0x6BD3,0x9F79, // + 0x6BD4,0x94E4, // + 0x6BD8,0x94F9, // + 0x6BDB,0x96D1, // + 0x6BDF,0x9F7A, // + 0x6BEB,0x9F7C, // + 0x6BEC,0x9F7B, // + 0x6BEF,0x9F7E, // + 0x6BF3,0x9F7D, // + 0x6C08,0x9F81, // + 0x6C0F,0x8E81, // + 0x6C11,0x96AF, // + 0x6C13,0x9F82, // + 0x6C14,0x9F83, // + 0x6C17,0x8B43, // + 0x6C1B,0x9F84, // + 0x6C23,0x9F86, // + 0x6C24,0x9F85, // + 0x6C34,0x9085, // + 0x6C37,0x9558, // + 0x6C38,0x8969, // + 0x6C3E,0x94C3, // + 0x6C40,0x92F3, // + 0x6C41,0x8F60, // + 0x6C42,0x8B81, // + 0x6C4E,0x94C4, // + 0x6C50,0x8EAC, // + 0x6C55,0x9F88, // + 0x6C57,0x8ABE, // + 0x6C5A,0x8998, // + 0x6C5D,0x93F0, // + 0x6C5E,0x9F87, // + 0x6C5F,0x8D5D, // + 0x6C60,0x9272, // + 0x6C62,0x9F89, // + 0x6C68,0x9F91, // + 0x6C6A,0x9F8A, // + 0x6C70,0x91BF, // + 0x6C72,0x8B82, // + 0x6C73,0x9F92, // + 0x6C7A,0x8C88, // + 0x6C7D,0x8B44, // + 0x6C7E,0x9F90, // + 0x6C81,0x9F8E, // + 0x6C82,0x9F8B, // + 0x6C83,0x9780, // + 0x6C88,0x92BE, // + 0x6C8C,0x93D7, // + 0x6C8D,0x9F8C, // + 0x6C90,0x9F94, // + 0x6C92,0x9F93, // + 0x6C93,0x8C42, // + 0x6C96,0x89AB, // + 0x6C99,0x8DB9, // + 0x6C9A,0x9F8D, // + 0x6C9B,0x9F8F, // + 0x6CA1,0x9676, // + 0x6CA2,0x91F2, // + 0x6CAB,0x9697, // + 0x6CAE,0x9F9C, // + 0x6CB1,0x9F9D, // + 0x6CB3,0x89CD, // + 0x6CB8,0x95A6, // + 0x6CB9,0x96FB, // + 0x6CBA,0x9F9F, // + 0x6CBB,0x8EA1, // + 0x6CBC,0x8FC0, // + 0x6CBD,0x9F98, // + 0x6CBE,0x9F9E, // + 0x6CBF,0x8988, // + 0x6CC1,0x8BB5, // + 0x6CC4,0x9F95, // + 0x6CC5,0x9F9A, // + 0x6CC9,0x90F2, // + 0x6CCA,0x9491, // + 0x6CCC,0x94E5, // + 0x6CD3,0x9F97, // + 0x6CD5,0x9640, // + 0x6CD7,0x9F99, // + 0x6CD9,0x9FA2, // + 0x6CDB,0x9FA0, // + 0x6CDD,0x9F9B, // + 0x6CE1,0x9641, // + 0x6CE2,0x9467, // + 0x6CE3,0x8B83, // + 0x6CE5,0x9344, // + 0x6CE8,0x928D, // + 0x6CEA,0x9FA3, // + 0x6CEF,0x9FA1, // + 0x6CF0,0x91D7, // + 0x6CF1,0x9F96, // + 0x6CF3,0x896A, // + 0x6D0B,0x976D, // + 0x6D0C,0x9FAE, // + 0x6D12,0x9FAD, // + 0x6D17,0x90F4, // + 0x6D19,0x9FAA, // + 0x6D1B,0x978C, // + 0x6D1E,0x93B4, // + 0x6D1F,0x9FA4, // + 0x6D25,0x92C3, // + 0x6D29,0x896B, // + 0x6D2A,0x8D5E, // + 0x6D2B,0x9FA7, // + 0x6D32,0x8F46, // + 0x6D33,0x9FAC, // + 0x6D35,0x9FAB, // + 0x6D36,0x9FA6, // + 0x6D38,0x9FA9, // + 0x6D3B,0x8A88, // + 0x6D3D,0x9FA8, // + 0x6D3E,0x9468, // + 0x6D41,0x97AC, // + 0x6D44,0x8FF2, // + 0x6D45,0x90F3, // + 0x6D59,0x9FB4, // + 0x6D5A,0x9FB2, // + 0x6D5C,0x956C, // + 0x6D63,0x9FAF, // + 0x6D64,0x9FB1, // + 0x6D66,0x8959, // + 0x6D69,0x8D5F, // + 0x6D6A,0x9851, // + 0x6D6C,0x8A5C, // + 0x6D6E,0x9582, // + 0x6D74,0x9781, // + 0x6D77,0x8A43, // + 0x6D78,0x905A, // + 0x6D79,0x9FB3, // + 0x6D85,0x9FB8, // + 0x6D88,0x8FC1, // + 0x6D8C,0x974F, // + 0x6D8E,0x9FB5, // + 0x6D93,0x9FB0, // + 0x6D95,0x9FB6, // + 0x6D99,0x97DC, // + 0x6D9B,0x9393, // + 0x6D9C,0x93C0, // + 0x6DAF,0x8A55, // + 0x6DB2,0x8974, // + 0x6DB5,0x9FBC, // + 0x6DB8,0x9FBF, // + 0x6DBC,0x97C1, // + 0x6DC0,0x9784, // + 0x6DC5,0x9FC6, // + 0x6DC6,0x9FC0, // + 0x6DC7,0x9FBD, // + 0x6DCB,0x97D2, // + 0x6DCC,0x9FC3, // + 0x6DD1,0x8F69, // + 0x6DD2,0x9FC5, // + 0x6DD5,0x9FCA, // + 0x6DD8,0x9391, // + 0x6DD9,0x9FC8, // + 0x6DDE,0x9FC2, // + 0x6DE1,0x9257, // + 0x6DE4,0x9FC9, // + 0x6DE6,0x9FBE, // + 0x6DE8,0x9FC4, // + 0x6DEA,0x9FCB, // + 0x6DEB,0x88FA, // + 0x6DEC,0x9FC1, // + 0x6DEE,0x9FCC, // + 0x6DF3,0x8F7E, // + 0x6DF5,0x95A3, // + 0x6DF7,0x8DAC, // + 0x6DF9,0x9FB9, // + 0x6DFA,0x9FC7, // + 0x6DFB,0x9359, // + 0x6E05,0x90B4, // + 0x6E07,0x8A89, // + 0x6E08,0x8DCF, // + 0x6E09,0x8FC2, // + 0x6E0A,0x9FBB, // + 0x6E0B,0x8F61, // + 0x6E13,0x8C6B, // + 0x6E15,0x9FBA, // + 0x6E19,0x9FD0, // + 0x6E1A,0x8F8D, // + 0x6E1B,0x8CB8, // + 0x6E1D,0x9FDF, // + 0x6E1F,0x9FD9, // + 0x6E20,0x8B94, // + 0x6E21,0x936E, // + 0x6E23,0x9FD4, // + 0x6E24,0x9FDD, // + 0x6E25,0x88AD, // + 0x6E26,0x8951, // + 0x6E29,0x89B7, // + 0x6E2B,0x9FD6, // + 0x6E2C,0x91AA, // + 0x6E2D,0x9FCD, // + 0x6E2E,0x9FCF, // + 0x6E2F,0x8D60, // + 0x6E38,0x9FE0, // + 0x6E3A,0x9FDB, // + 0x6E3E,0x9FD3, // + 0x6E43,0x9FDA, // + 0x6E4A,0x96A9, // + 0x6E4D,0x9FD8, // + 0x6E4E,0x9FDC, // + 0x6E56,0x8CCE, // + 0x6E58,0x8FC3, // + 0x6E5B,0x9258, // + 0x6E5F,0x9FD2, // + 0x6E67,0x974E, // + 0x6E6B,0x9FD5, // + 0x6E6E,0x9FCE, // + 0x6E6F,0x9392, // + 0x6E72,0x9FD1, // + 0x6E76,0x9FD7, // + 0x6E7E,0x9870, // + 0x6E7F,0x8EBC, // + 0x6E80,0x969E, // + 0x6E82,0x9FE1, // + 0x6E8C,0x94AC, // + 0x6E8F,0x9FED, // + 0x6E90,0x8CB9, // + 0x6E96,0x8F80, // + 0x6E98,0x9FE3, // + 0x6E9C,0x97AD, // + 0x6E9D,0x8D61, // + 0x6E9F,0x9FF0, // + 0x6EA2,0x88EC, // + 0x6EA5,0x9FEE, // + 0x6EAA,0x9FE2, // + 0x6EAF,0x9FE8, // + 0x6EB2,0x9FEA, // + 0x6EB6,0x976E, // + 0x6EB7,0x9FE5, // + 0x6EBA,0x934D, // + 0x6EBD,0x9FE7, // + 0x6EC2,0x9FEF, // + 0x6EC4,0x9FE9, // + 0x6EC5,0x96C5, // + 0x6EC9,0x9FE4, // + 0x6ECB,0x8EA0, // + 0x6ECC,0x9FFC, // + 0x6ED1,0x8A8A, // + 0x6ED3,0x9FE6, // + 0x6ED4,0x9FEB, // + 0x6ED5,0x9FEC, // + 0x6EDD,0x91EA, // + 0x6EDE,0x91D8, // + 0x6EEC,0x9FF4, // + 0x6EEF,0x9FFA, // + 0x6EF2,0x9FF8, // + 0x6EF4,0x9348, // + 0x6EF7,0xE042, // + 0x6EF8,0x9FF5, // + 0x6EFE,0x9FF6, // + 0x6EFF,0x9FDE, // + 0x6F01,0x8B99, // + 0x6F02,0x9559, // + 0x6F06,0x8EBD, // + 0x6F09,0x8D97, // + 0x6F0F,0x9852, // + 0x6F11,0x9FF2, // + 0x6F13,0xE041, // + 0x6F14,0x8989, // + 0x6F15,0x9186, // + 0x6F20,0x9499, // + 0x6F22,0x8ABF, // + 0x6F23,0x97F8, // + 0x6F2B,0x969F, // + 0x6F2C,0x92D0, // + 0x6F31,0x9FF9, // + 0x6F32,0x9FFB, // + 0x6F38,0x9151, // + 0x6F3E,0xE040, // + 0x6F3F,0x9FF7, // + 0x6F41,0x9FF1, // + 0x6F45,0x8AC1, // + 0x6F54,0x8C89, // + 0x6F58,0xE04E, // + 0x6F5B,0xE049, // + 0x6F5C,0x90F6, // + 0x6F5F,0x8A83, // + 0x6F64,0x8F81, // + 0x6F66,0xE052, // + 0x6F6D,0xE04B, // + 0x6F6E,0x92AA, // + 0x6F6F,0xE048, // + 0x6F70,0x92D7, // + 0x6F74,0xE06B, // + 0x6F78,0xE045, // + 0x6F7A,0xE044, // + 0x6F7C,0xE04D, // + 0x6F80,0xE047, // + 0x6F81,0xE046, // + 0x6F82,0xE04C, // + 0x6F84,0x909F, // + 0x6F86,0xE043, // + 0x6F8E,0xE04F, // + 0x6F91,0xE050, // + 0x6F97,0x8AC0, // + 0x6FA1,0xE055, // + 0x6FA3,0xE054, // + 0x6FA4,0xE056, // + 0x6FAA,0xE059, // + 0x6FB1,0x9362, // + 0x6FB3,0xE053, // + 0x6FB9,0xE057, // + 0x6FC0,0x8C83, // + 0x6FC1,0x91F7, // + 0x6FC2,0xE051, // + 0x6FC3,0x945A, // + 0x6FC6,0xE058, // + 0x6FD4,0xE05D, // + 0x6FD8,0xE05E, // + 0x6FDB,0xE061, // + 0x6FDF,0xE05A, // + 0x6FE0,0x8D8A, // + 0x6FE1,0x9447, // + 0x6FE4,0x9FB7, // + 0x6FEB,0x9794, // + 0x6FEC,0xE05C, // + 0x6FEE,0xE060, // + 0x6FEF,0x91F3, // + 0x6FF1,0xE05F, // + 0x6FF3,0xE04A, // + 0x6FF6,0xE889, // + 0x6FFA,0xE064, // + 0x6FFE,0xE068, // + 0x7001,0xE066, // + 0x7009,0xE062, // + 0x700B,0xE063, // + 0x700F,0xE067, // + 0x7011,0xE065, // + 0x7015,0x956D, // + 0x7018,0xE06D, // + 0x701A,0xE06A, // + 0x701B,0xE069, // + 0x701D,0xE06C, // + 0x701E,0x93D2, // + 0x701F,0xE06E, // + 0x7026,0x9295, // + 0x7027,0x91EB, // + 0x702C,0x90A3, // + 0x7030,0xE06F, // + 0x7032,0xE071, // + 0x703E,0xE070, // + 0x704C,0x9FF3, // + 0x7051,0xE072, // + 0x7058,0x93E5, // + 0x7063,0xE073, // + 0x706B,0x89CE, // + 0x706F,0x9394, // + 0x7070,0x8A44, // + 0x7078,0x8B84, // + 0x707C,0x8EDC, // + 0x707D,0x8DD0, // + 0x7089,0x9846, // + 0x708A,0x9086, // + 0x708E,0x898A, // + 0x7092,0xE075, // + 0x7099,0xE074, // + 0x70AC,0xE078, // + 0x70AD,0x9259, // + 0x70AE,0xE07B, // + 0x70AF,0xE076, // + 0x70B3,0xE07A, // + 0x70B8,0xE079, // + 0x70B9,0x935F, // + 0x70BA,0x88D7, // + 0x70C8,0x97F3, // + 0x70CB,0xE07D, // + 0x70CF,0x8947, // + 0x70D9,0xE080, // + 0x70DD,0xE07E, // + 0x70DF,0xE07C, // + 0x70F1,0xE077, // + 0x70F9,0x9642, // + 0x70FD,0xE082, // + 0x7109,0xE081, // + 0x7114,0x898B, // + 0x7119,0xE084, // + 0x711A,0x95B0, // + 0x711C,0xE083, // + 0x7121,0x96B3, // + 0x7126,0x8FC5, // + 0x7136,0x9152, // + 0x713C,0x8FC4, // + 0x7149,0x97F9, // + 0x714C,0xE08A, // + 0x714E,0x90F7, // + 0x7155,0xE086, // + 0x7156,0xE08B, // + 0x7159,0x898C, // + 0x7162,0xE089, // + 0x7164,0x9481, // + 0x7165,0xE085, // + 0x7166,0xE088, // + 0x7167,0x8FC6, // + 0x7169,0x94CF, // + 0x716C,0xE08C, // + 0x716E,0x8ECF, // + 0x717D,0x90F8, // + 0x7184,0xE08F, // + 0x7188,0xE087, // + 0x718A,0x8C46, // + 0x718F,0xE08D, // + 0x7194,0x976F, // + 0x7195,0xE090, // + 0x7199,0xEAA4, // + 0x719F,0x8F6E, // + 0x71A8,0xE091, // + 0x71AC,0xE092, // + 0x71B1,0x944D, // + 0x71B9,0xE094, // + 0x71BE,0xE095, // + 0x71C3,0x9452, // + 0x71C8,0x9395, // + 0x71C9,0xE097, // + 0x71CE,0xE099, // + 0x71D0,0x97D3, // + 0x71D2,0xE096, // + 0x71D4,0xE098, // + 0x71D5,0x898D, // + 0x71D7,0xE093, // + 0x71DF,0x9A7A, // + 0x71E0,0xE09A, // + 0x71E5,0x9187, // + 0x71E6,0x8E57, // + 0x71E7,0xE09C, // + 0x71EC,0xE09B, // + 0x71ED,0x9043, // + 0x71EE,0x99D7, // + 0x71F5,0xE09D, // + 0x71F9,0xE09F, // + 0x71FB,0xE08E, // + 0x71FC,0xE09E, // + 0x71FF,0xE0A0, // + 0x7206,0x949A, // + 0x720D,0xE0A1, // + 0x7210,0xE0A2, // + 0x721B,0xE0A3, // + 0x7228,0xE0A4, // + 0x722A,0x92DC, // + 0x722C,0xE0A6, // + 0x722D,0xE0A5, // + 0x7230,0xE0A7, // + 0x7232,0xE0A8, // + 0x7235,0x8EDD, // + 0x7236,0x9583, // + 0x723A,0x96EA, // + 0x723B,0xE0A9, // + 0x723C,0xE0AA, // + 0x723D,0x9175, // + 0x723E,0x8EA2, // + 0x723F,0xE0AB, // + 0x7240,0xE0AC, // + 0x7246,0xE0AD, // + 0x7247,0x95D0, // + 0x7248,0x94C5, // + 0x724B,0xE0AE, // + 0x724C,0x9476, // + 0x7252,0x92AB, // + 0x7258,0xE0AF, // + 0x7259,0x89E5, // + 0x725B,0x8B8D, // + 0x725D,0x96C4, // + 0x725F,0x96B4, // + 0x7261,0x89B2, // + 0x7262,0x9853, // + 0x7267,0x9671, // + 0x7269,0x95A8, // + 0x7272,0x90B5, // + 0x7274,0xE0B0, // + 0x7279,0x93C1, // + 0x727D,0x8CA1, // + 0x727E,0xE0B1, // + 0x7280,0x8DD2, // + 0x7281,0xE0B3, // + 0x7282,0xE0B2, // + 0x7287,0xE0B4, // + 0x7292,0xE0B5, // + 0x7296,0xE0B6, // + 0x72A0,0x8B5D, // + 0x72A2,0xE0B7, // + 0x72A7,0xE0B8, // + 0x72AC,0x8CA2, // + 0x72AF,0x94C6, // + 0x72B2,0xE0BA, // + 0x72B6,0x8FF3, // + 0x72B9,0xE0B9, // + 0x72C2,0x8BB6, // + 0x72C3,0xE0BB, // + 0x72C4,0xE0BD, // + 0x72C6,0xE0BC, // + 0x72CE,0xE0BE, // + 0x72D0,0x8CCF, // + 0x72D2,0xE0BF, // + 0x72D7,0x8BE7, // + 0x72D9,0x915F, // + 0x72DB,0x8D9D, // + 0x72E0,0xE0C1, // + 0x72E1,0xE0C2, // + 0x72E2,0xE0C0, // + 0x72E9,0x8EEB, // + 0x72EC,0x93C6, // + 0x72ED,0x8BB7, // + 0x72F7,0xE0C4, // + 0x72F8,0x924B, // + 0x72F9,0xE0C3, // + 0x72FC,0x9854, // + 0x72FD,0x9482, // + 0x730A,0xE0C7, // + 0x7316,0xE0C9, // + 0x7317,0xE0C6, // + 0x731B,0x96D2, // + 0x731C,0xE0C8, // + 0x731D,0xE0CA, // + 0x731F,0x97C2, // + 0x7325,0xE0CE, // + 0x7329,0xE0CD, // + 0x732A,0x9296, // + 0x732B,0x944C, // + 0x732E,0x8CA3, // + 0x732F,0xE0CC, // + 0x7334,0xE0CB, // + 0x7336,0x9750, // + 0x7337,0x9751, // + 0x733E,0xE0CF, // + 0x733F,0x898E, // + 0x7344,0x8D96, // + 0x7345,0x8E82, // + 0x734E,0xE0D0, // + 0x734F,0xE0D1, // + 0x7357,0xE0D3, // + 0x7363,0x8F62, // + 0x7368,0xE0D5, // + 0x736A,0xE0D4, // + 0x7370,0xE0D6, // + 0x7372,0x8A6C, // + 0x7375,0xE0D8, // + 0x7378,0xE0D7, // + 0x737A,0xE0DA, // + 0x737B,0xE0D9, // + 0x7384,0x8CBA, // + 0x7387,0x97A6, // + 0x7389,0x8BCA, // + 0x738B,0x89A4, // + 0x7396,0x8BE8, // + 0x73A9,0x8ADF, // + 0x73B2,0x97E6, // + 0x73B3,0xE0DC, // + 0x73BB,0xE0DE, // + 0x73C0,0xE0DF, // + 0x73C2,0x89CF, // + 0x73C8,0xE0DB, // + 0x73CA,0x8E58, // + 0x73CD,0x92BF, // + 0x73CE,0xE0DD, // + 0x73DE,0xE0E2, // + 0x73E0,0x8EEC, // + 0x73E5,0xE0E0, // + 0x73EA,0x8C5D, // + 0x73ED,0x94C7, // + 0x73EE,0xE0E1, // + 0x73F1,0xE0FC, // + 0x73F8,0xE0E7, // + 0x73FE,0x8CBB, // + 0x7403,0x8B85, // + 0x7405,0xE0E4, // + 0x7406,0x979D, // + 0x7409,0x97AE, // + 0x7422,0x91F4, // + 0x7425,0xE0E6, // + 0x7432,0xE0E8, // + 0x7433,0x97D4, // + 0x7434,0x8BD5, // + 0x7435,0x94FA, // + 0x7436,0x9469, // + 0x743A,0xE0E9, // + 0x743F,0xE0EB, // + 0x7441,0xE0EE, // + 0x7455,0xE0EA, // + 0x7459,0xE0ED, // + 0x745A,0x8CE8, // + 0x745B,0x896C, // + 0x745C,0xE0EF, // + 0x745E,0x9090, // + 0x745F,0xE0EC, // + 0x7460,0x97DA, // + 0x7463,0xE0F2, // + 0x7464,0xEAA2, // + 0x7469,0xE0F0, // + 0x746A,0xE0F3, // + 0x746F,0xE0E5, // + 0x7470,0xE0F1, // + 0x7473,0x8DBA, // + 0x7476,0xE0F4, // + 0x747E,0xE0F5, // + 0x7483,0x979E, // + 0x748B,0xE0F6, // + 0x749E,0xE0F7, // + 0x74A2,0xE0E3, // + 0x74A7,0xE0F8, // + 0x74B0,0x8AC2, // + 0x74BD,0x8EA3, // + 0x74CA,0xE0F9, // + 0x74CF,0xE0FA, // + 0x74D4,0xE0FB, // + 0x74DC,0x895A, // + 0x74E0,0xE140, // + 0x74E2,0x955A, // + 0x74E3,0xE141, // + 0x74E6,0x8AA2, // + 0x74E7,0xE142, // + 0x74E9,0xE143, // + 0x74EE,0xE144, // + 0x74F0,0xE146, // + 0x74F1,0xE147, // + 0x74F2,0xE145, // + 0x74F6,0x9572, // + 0x74F7,0xE149, // + 0x74F8,0xE148, // + 0x7503,0xE14B, // + 0x7504,0xE14A, // + 0x7505,0xE14C, // + 0x750C,0xE14D, // + 0x750D,0xE14F, // + 0x750E,0xE14E, // + 0x7511,0x8D99, // + 0x7513,0xE151, // + 0x7515,0xE150, // + 0x7518,0x8AC3, // + 0x751A,0x9072, // + 0x751E,0xE152, // + 0x751F,0x90B6, // + 0x7523,0x8E59, // + 0x7525,0x8999, // + 0x7526,0xE153, // + 0x7528,0x9770, // + 0x752B,0x95E1, // + 0x752C,0xE154, // + 0x7530,0x9363, // + 0x7531,0x9752, // + 0x7532,0x8D62, // + 0x7533,0x905C, // + 0x7537,0x926A, // + 0x7538,0x99B2, // + 0x753A,0x92AC, // + 0x753B,0x89E6, // + 0x753C,0xE155, // + 0x7544,0xE156, // + 0x7549,0xE159, // + 0x754A,0xE158, // + 0x754B,0x9DC0, // + 0x754C,0x8A45, // + 0x754D,0xE157, // + 0x754F,0x88D8, // + 0x7551,0x94A8, // + 0x7554,0x94C8, // + 0x7559,0x97AF, // + 0x755A,0xE15C, // + 0x755B,0xE15A, // + 0x755C,0x927B, // + 0x755D,0x90A4, // + 0x7560,0x94A9, // + 0x7562,0x954C, // + 0x7564,0xE15E, // + 0x7565,0x97AA, // + 0x7566,0x8C6C, // + 0x7567,0xE15F, // + 0x7569,0xE15D, // + 0x756A,0x94D4, // + 0x756B,0xE160, // + 0x756D,0xE161, // + 0x7570,0x88D9, // + 0x7573,0x8FF4, // + 0x7574,0xE166, // + 0x7576,0xE163, // + 0x7577,0x93EB, // + 0x7578,0xE162, // + 0x757F,0x8B45, // + 0x7582,0xE169, // + 0x7586,0xE164, // + 0x7587,0xE165, // + 0x7589,0xE168, // + 0x758A,0xE167, // + 0x758B,0x9544, // + 0x758E,0x9161, // + 0x758F,0x9160, // + 0x7591,0x8B5E, // + 0x7594,0xE16A, // + 0x759A,0xE16B, // + 0x759D,0xE16C, // + 0x75A3,0xE16E, // + 0x75A5,0xE16D, // + 0x75AB,0x8975, // + 0x75B1,0xE176, // + 0x75B2,0x94E6, // + 0x75B3,0xE170, // + 0x75B5,0xE172, // + 0x75B8,0xE174, // + 0x75B9,0x905D, // + 0x75BC,0xE175, // + 0x75BD,0xE173, // + 0x75BE,0x8EBE, // + 0x75C2,0xE16F, // + 0x75C3,0xE171, // + 0x75C5,0x9561, // + 0x75C7,0x8FC7, // + 0x75CA,0xE178, // + 0x75CD,0xE177, // + 0x75D2,0xE179, // + 0x75D4,0x8EA4, // + 0x75D5,0x8DAD, // + 0x75D8,0x9397, // + 0x75D9,0xE17A, // + 0x75DB,0x92C9, // + 0x75DE,0xE17C, // + 0x75E2,0x979F, // + 0x75E3,0xE17B, // + 0x75E9,0x9189, // + 0x75F0,0xE182, // + 0x75F2,0xE184, // + 0x75F3,0xE185, // + 0x75F4,0x9273, // + 0x75FA,0xE183, // + 0x75FC,0xE180, // + 0x75FE,0xE17D, // + 0x75FF,0xE17E, // + 0x7601,0xE181, // + 0x7609,0xE188, // + 0x760B,0xE186, // + 0x760D,0xE187, // + 0x761F,0xE189, // + 0x7620,0xE18B, // + 0x7621,0xE18C, // + 0x7622,0xE18D, // + 0x7624,0xE18E, // + 0x7627,0xE18A, // + 0x7630,0xE190, // + 0x7634,0xE18F, // + 0x763B,0xE191, // + 0x7642,0x97C3, // + 0x7646,0xE194, // + 0x7647,0xE192, // + 0x7648,0xE193, // + 0x764C,0x8AE0, // + 0x7652,0x96FC, // + 0x7656,0x95C8, // + 0x7658,0xE196, // + 0x765C,0xE195, // + 0x7661,0xE197, // + 0x7662,0xE198, // + 0x7667,0xE19C, // + 0x7668,0xE199, // + 0x7669,0xE19A, // + 0x766A,0xE19B, // + 0x766C,0xE19D, // + 0x7670,0xE19E, // + 0x7672,0xE19F, // + 0x7676,0xE1A0, // + 0x7678,0xE1A1, // + 0x767A,0x94AD, // + 0x767B,0x936F, // + 0x767C,0xE1A2, // + 0x767D,0x9492, // + 0x767E,0x9553, // + 0x7680,0xE1A3, // + 0x7683,0xE1A4, // + 0x7684,0x9349, // + 0x7686,0x8A46, // + 0x7687,0x8D63, // + 0x7688,0xE1A5, // + 0x768B,0xE1A6, // + 0x768E,0xE1A7, // + 0x7690,0x8E48, // + 0x7693,0xE1A9, // + 0x7696,0xE1A8, // + 0x7699,0xE1AA, // + 0x769A,0xE1AB, // + 0x76AE,0x94E7, // + 0x76B0,0xE1AC, // + 0x76B4,0xE1AD, // + 0x76B7,0xEA89, // + 0x76B8,0xE1AE, // + 0x76B9,0xE1AF, // + 0x76BA,0xE1B0, // + 0x76BF,0x8E4D, // + 0x76C2,0xE1B1, // + 0x76C3,0x9475, // + 0x76C6,0x967E, // + 0x76C8,0x896D, // + 0x76CA,0x8976, // + 0x76CD,0xE1B2, // + 0x76D2,0xE1B4, // + 0x76D6,0xE1B3, // + 0x76D7,0x9390, // + 0x76DB,0x90B7, // + 0x76DC,0x9F58, // + 0x76DE,0xE1B5, // + 0x76DF,0x96BF, // + 0x76E1,0xE1B6, // + 0x76E3,0x8AC4, // + 0x76E4,0x94D5, // + 0x76E5,0xE1B7, // + 0x76E7,0xE1B8, // + 0x76EA,0xE1B9, // + 0x76EE,0x96DA, // + 0x76F2,0x96D3, // + 0x76F4,0x92BC, // + 0x76F8,0x918A, // + 0x76FB,0xE1BB, // + 0x76FE,0x8F82, // + 0x7701,0x8FC8, // + 0x7704,0xE1BE, // + 0x7707,0xE1BD, // + 0x7708,0xE1BC, // + 0x7709,0x94FB, // + 0x770B,0x8AC5, // + 0x770C,0x8CA7, // + 0x771B,0xE1C4, // + 0x771E,0xE1C1, // + 0x771F,0x905E, // + 0x7720,0x96B0, // + 0x7724,0xE1C0, // + 0x7725,0xE1C2, // + 0x7726,0xE1C3, // + 0x7729,0xE1BF, // + 0x7737,0xE1C5, // + 0x7738,0xE1C6, // + 0x773A,0x92AD, // + 0x773C,0x8AE1, // + 0x7740,0x9285, // + 0x7747,0xE1C7, // + 0x775A,0xE1C8, // + 0x775B,0xE1CB, // + 0x7761,0x9087, // + 0x7763,0x93C2, // + 0x7765,0xE1CC, // + 0x7766,0x9672, // + 0x7768,0xE1C9, // + 0x776B,0xE1CA, // + 0x7779,0xE1CF, // + 0x777E,0xE1CE, // + 0x777F,0xE1CD, // + 0x778B,0xE1D1, // + 0x778E,0xE1D0, // + 0x7791,0xE1D2, // + 0x779E,0xE1D4, // + 0x77A0,0xE1D3, // + 0x77A5,0x95CB, // + 0x77AC,0x8F75, // + 0x77AD,0x97C4, // + 0x77B0,0xE1D5, // + 0x77B3,0x93B5, // + 0x77B6,0xE1D6, // + 0x77B9,0xE1D7, // + 0x77BB,0xE1DB, // + 0x77BC,0xE1D9, // + 0x77BD,0xE1DA, // + 0x77BF,0xE1D8, // + 0x77C7,0xE1DC, // + 0x77CD,0xE1DD, // + 0x77D7,0xE1DE, // + 0x77DA,0xE1DF, // + 0x77DB,0x96B5, // + 0x77DC,0xE1E0, // + 0x77E2,0x96EE, // + 0x77E3,0xE1E1, // + 0x77E5,0x926D, // + 0x77E7,0x948A, // + 0x77E9,0x8BE9, // + 0x77ED,0x925A, // + 0x77EE,0xE1E2, // + 0x77EF,0x8BB8, // + 0x77F3,0x90CE, // + 0x77FC,0xE1E3, // + 0x7802,0x8DBB, // + 0x780C,0xE1E4, // + 0x7812,0xE1E5, // + 0x7814,0x8CA4, // + 0x7815,0x8DD3, // + 0x7820,0xE1E7, // + 0x7825,0x9375, // + 0x7826,0x8DD4, // + 0x7827,0x8B6D, // + 0x7832,0x9643, // + 0x7834,0x946A, // + 0x783A,0x9376, // + 0x783F,0x8D7B, // + 0x7845,0xE1E9, // + 0x785D,0x8FC9, // + 0x786B,0x97B0, // + 0x786C,0x8D64, // + 0x786F,0x8CA5, // + 0x7872,0x94A1, // + 0x7874,0xE1EB, // + 0x787C,0xE1ED, // + 0x7881,0x8CE9, // + 0x7886,0xE1EC, // + 0x7887,0x92F4, // + 0x788C,0xE1EF, // + 0x788D,0x8A56, // + 0x788E,0xE1EA, // + 0x7891,0x94E8, // + 0x7893,0x894F, // + 0x7895,0x8DEA, // + 0x7897,0x9871, // + 0x789A,0xE1EE, // + 0x78A3,0xE1F0, // + 0x78A7,0x95C9, // + 0x78A9,0x90D7, // + 0x78AA,0xE1F2, // + 0x78AF,0xE1F3, // + 0x78B5,0xE1F1, // + 0x78BA,0x8A6D, // + 0x78BC,0xE1F9, // + 0x78BE,0xE1F8, // + 0x78C1,0x8EA5, // + 0x78C5,0xE1FA, // + 0x78C6,0xE1F5, // + 0x78CA,0xE1FB, // + 0x78CB,0xE1F6, // + 0x78D0,0x94D6, // + 0x78D1,0xE1F4, // + 0x78D4,0xE1F7, // + 0x78DA,0xE241, // + 0x78E7,0xE240, // + 0x78E8,0x9681, // + 0x78EC,0xE1FC, // + 0x78EF,0x88E9, // + 0x78F4,0xE243, // + 0x78FD,0xE242, // + 0x7901,0x8FCA, // + 0x7907,0xE244, // + 0x790E,0x9162, // + 0x7911,0xE246, // + 0x7912,0xE245, // + 0x7919,0xE247, // + 0x7926,0xE1E6, // + 0x792A,0xE1E8, // + 0x792B,0xE249, // + 0x792C,0xE248, // + 0x793A,0x8EA6, // + 0x793C,0x97E7, // + 0x793E,0x8ED0, // + 0x7940,0xE24A, // + 0x7941,0x8C56, // + 0x7947,0x8B5F, // + 0x7948,0x8B46, // + 0x7949,0x8E83, // + 0x7950,0x9753, // + 0x7953,0xE250, // + 0x7955,0xE24F, // + 0x7956,0x9163, // + 0x7957,0xE24C, // + 0x795A,0xE24E, // + 0x795D,0x8F6A, // + 0x795E,0x905F, // + 0x795F,0xE24D, // + 0x7960,0xE24B, // + 0x7962,0x9449, // + 0x7965,0x8FCB, // + 0x796D,0x8DD5, // + 0x7977,0x9398, // + 0x797A,0xE251, // + 0x797F,0xE252, // + 0x7980,0xE268, // + 0x7981,0x8BD6, // + 0x7984,0x985C, // + 0x7985,0x9154, // + 0x798A,0xE253, // + 0x798D,0x89D0, // + 0x798E,0x92F5, // + 0x798F,0x959F, // + 0x799D,0xE254, // + 0x79A6,0x8B9A, // + 0x79A7,0xE255, // + 0x79AA,0xE257, // + 0x79AE,0xE258, // + 0x79B0,0x9448, // + 0x79B3,0xE259, // + 0x79B9,0xE25A, // + 0x79BD,0x8BD7, // + 0x79BE,0x89D1, // + 0x79BF,0x93C3, // + 0x79C0,0x8F47, // + 0x79C1,0x8E84, // + 0x79C9,0xE25C, // + 0x79CB,0x8F48, // + 0x79D1,0x89C8, // + 0x79D2,0x9562, // + 0x79D5,0xE25D, // + 0x79D8,0x94E9, // + 0x79DF,0x9164, // + 0x79E1,0xE260, // + 0x79E3,0xE261, // + 0x79E4,0x9489, // + 0x79E6,0x9060, // + 0x79E7,0xE25E, // + 0x79E9,0x9281, // + 0x79EC,0xE25F, // + 0x79F0,0x8FCC, // + 0x79FB,0x88DA, // + 0x7A00,0x8B48, // + 0x7A08,0xE262, // + 0x7A0B,0x92F6, // + 0x7A0D,0xE263, // + 0x7A0E,0x90C5, // + 0x7A14,0x96AB, // + 0x7A17,0x9542, // + 0x7A18,0xE264, // + 0x7A19,0xE265, // + 0x7A1A,0x9274, // + 0x7A1C,0x97C5, // + 0x7A1F,0xE267, // + 0x7A20,0xE266, // + 0x7A2E,0x8EED, // + 0x7A31,0xE269, // + 0x7A32,0x88EE, // + 0x7A37,0xE26C, // + 0x7A3B,0xE26A, // + 0x7A3C,0x89D2, // + 0x7A3D,0x8C6D, // + 0x7A3E,0xE26B, // + 0x7A3F,0x8D65, // + 0x7A40,0x8D92, // + 0x7A42,0x95E4, // + 0x7A43,0xE26D, // + 0x7A46,0x9673, // + 0x7A49,0xE26F, // + 0x7A4D,0x90CF, // + 0x7A4E,0x896E, // + 0x7A4F,0x89B8, // + 0x7A50,0x88AA, // + 0x7A57,0xE26E, // + 0x7A61,0xE270, // + 0x7A62,0xE271, // + 0x7A63,0x8FF5, // + 0x7A69,0xE272, // + 0x7A6B,0x8A6E, // + 0x7A70,0xE274, // + 0x7A74,0x8C8A, // + 0x7A76,0x8B86, // + 0x7A79,0xE275, // + 0x7A7A,0x8BF3, // + 0x7A7D,0xE276, // + 0x7A7F,0x90FA, // + 0x7A81,0x93CB, // + 0x7A83,0x90DE, // + 0x7A84,0x8DF3, // + 0x7A88,0xE277, // + 0x7A92,0x9282, // + 0x7A93,0x918B, // + 0x7A95,0xE279, // + 0x7A96,0xE27B, // + 0x7A97,0xE278, // + 0x7A98,0xE27A, // + 0x7A9F,0x8C41, // + 0x7AA9,0xE27C, // + 0x7AAA,0x8C45, // + 0x7AAE,0x8B87, // + 0x7AAF,0x9771, // + 0x7AB0,0xE27E, // + 0x7AB6,0xE280, // + 0x7ABA,0x894D, // + 0x7ABF,0xE283, // + 0x7AC3,0x8A96, // + 0x7AC4,0xE282, // + 0x7AC5,0xE281, // + 0x7AC7,0xE285, // + 0x7AC8,0xE27D, // + 0x7ACA,0xE286, // + 0x7ACB,0x97A7, // + 0x7ACD,0xE287, // + 0x7ACF,0xE288, // + 0x7AD2,0x9AF2, // + 0x7AD3,0xE28A, // + 0x7AD5,0xE289, // + 0x7AD9,0xE28B, // + 0x7ADA,0xE28C, // + 0x7ADC,0x97B3, // + 0x7ADD,0xE28D, // + 0x7ADF,0xE8ED, // + 0x7AE0,0x8FCD, // + 0x7AE1,0xE28E, // + 0x7AE2,0xE28F, // + 0x7AE3,0x8F76, // + 0x7AE5,0x93B6, // + 0x7AE6,0xE290, // + 0x7AEA,0x9247, // + 0x7AED,0xE291, // + 0x7AF0,0xE292, // + 0x7AF6,0x8BA3, // + 0x7AF8,0x995E, // + 0x7AF9,0x927C, // + 0x7AFA,0x8EB1, // + 0x7AFF,0x8AC6, // + 0x7B02,0xE293, // + 0x7B04,0xE2A0, // + 0x7B06,0xE296, // + 0x7B08,0x8B88, // + 0x7B0A,0xE295, // + 0x7B0B,0xE2A2, // + 0x7B0F,0xE294, // + 0x7B11,0x8FCE, // + 0x7B18,0xE298, // + 0x7B19,0xE299, // + 0x7B1B,0x934A, // + 0x7B1E,0xE29A, // + 0x7B20,0x8A7D, // + 0x7B25,0x9079, // + 0x7B26,0x9584, // + 0x7B28,0xE29C, // + 0x7B2C,0x91E6, // + 0x7B33,0xE297, // + 0x7B35,0xE29B, // + 0x7B36,0xE29D, // + 0x7B39,0x8DF9, // + 0x7B45,0xE2A4, // + 0x7B46,0x954D, // + 0x7B48,0x94A4, // + 0x7B49,0x9399, // + 0x7B4B,0x8BD8, // + 0x7B4C,0xE2A3, // + 0x7B4D,0xE2A1, // + 0x7B4F,0x94B3, // + 0x7B50,0xE29E, // + 0x7B51,0x927D, // + 0x7B52,0x939B, // + 0x7B54,0x939A, // + 0x7B56,0x8DF4, // + 0x7B5D,0xE2B6, // + 0x7B65,0xE2A6, // + 0x7B67,0xE2A8, // + 0x7B6C,0xE2AB, // + 0x7B6E,0xE2AC, // + 0x7B70,0xE2A9, // + 0x7B71,0xE2AA, // + 0x7B74,0xE2A7, // + 0x7B75,0xE2A5, // + 0x7B7A,0xE29F, // + 0x7B86,0x95CD, // + 0x7B87,0x89D3, // + 0x7B8B,0xE2B3, // + 0x7B8D,0xE2B0, // + 0x7B8F,0xE2B5, // + 0x7B92,0xE2B4, // + 0x7B94,0x9493, // + 0x7B95,0x96A5, // + 0x7B97,0x8E5A, // + 0x7B98,0xE2AE, // + 0x7B99,0xE2B7, // + 0x7B9A,0xE2B2, // + 0x7B9C,0xE2B1, // + 0x7B9D,0xE2AD, // + 0x7B9F,0xE2AF, // + 0x7BA1,0x8AC7, // + 0x7BAA,0x925C, // + 0x7BAD,0x90FB, // + 0x7BB1,0x94A0, // + 0x7BB4,0xE2BC, // + 0x7BB8,0x94A2, // + 0x7BC0,0x90DF, // + 0x7BC1,0xE2B9, // + 0x7BC4,0x94CD, // + 0x7BC6,0xE2BD, // + 0x7BC7,0x95D1, // + 0x7BC9,0x927A, // + 0x7BCB,0xE2B8, // + 0x7BCC,0xE2BA, // + 0x7BCF,0xE2BB, // + 0x7BDD,0xE2BE, // + 0x7BE0,0x8EC2, // + 0x7BE4,0x93C4, // + 0x7BE5,0xE2C3, // + 0x7BE6,0xE2C2, // + 0x7BE9,0xE2BF, // + 0x7BED,0x9855, // + 0x7BF3,0xE2C8, // + 0x7BF6,0xE2CC, // + 0x7BF7,0xE2C9, // + 0x7C00,0xE2C5, // + 0x7C07,0xE2C6, // + 0x7C0D,0xE2CB, // + 0x7C11,0xE2C0, // + 0x7C12,0x99D3, // + 0x7C13,0xE2C7, // + 0x7C14,0xE2C1, // + 0x7C17,0xE2CA, // + 0x7C1F,0xE2D0, // + 0x7C21,0x8AC8, // + 0x7C23,0xE2CD, // + 0x7C27,0xE2CE, // + 0x7C2A,0xE2CF, // + 0x7C2B,0xE2D2, // + 0x7C37,0xE2D1, // + 0x7C38,0x94F4, // + 0x7C3D,0xE2D3, // + 0x7C3E,0x97FA, // + 0x7C3F,0x95EB, // + 0x7C40,0xE2D8, // + 0x7C43,0xE2D5, // + 0x7C4C,0xE2D4, // + 0x7C4D,0x90D0, // + 0x7C4F,0xE2D7, // + 0x7C50,0xE2D9, // + 0x7C54,0xE2D6, // + 0x7C56,0xE2DD, // + 0x7C58,0xE2DA, // + 0x7C5F,0xE2DB, // + 0x7C60,0xE2C4, // + 0x7C64,0xE2DC, // + 0x7C65,0xE2DE, // + 0x7C6C,0xE2DF, // + 0x7C73,0x95C4, // + 0x7C75,0xE2E0, // + 0x7C7E,0x96E0, // + 0x7C81,0x8BCC, // + 0x7C82,0x8C48, // + 0x7C83,0xE2E1, // + 0x7C89,0x95B2, // + 0x7C8B,0x9088, // + 0x7C8D,0x96AE, // + 0x7C90,0xE2E2, // + 0x7C92,0x97B1, // + 0x7C95,0x9494, // + 0x7C97,0x9165, // + 0x7C98,0x9453, // + 0x7C9B,0x8F6C, // + 0x7C9F,0x88BE, // + 0x7CA1,0xE2E7, // + 0x7CA2,0xE2E5, // + 0x7CA4,0xE2E3, // + 0x7CA5,0x8A9F, // + 0x7CA7,0x8FCF, // + 0x7CA8,0xE2E8, // + 0x7CAB,0xE2E6, // + 0x7CAD,0xE2E4, // + 0x7CAE,0xE2EC, // + 0x7CB1,0xE2EB, // + 0x7CB2,0xE2EA, // + 0x7CB3,0xE2E9, // + 0x7CB9,0xE2ED, // + 0x7CBD,0xE2EE, // + 0x7CBE,0x90B8, // + 0x7CC0,0xE2EF, // + 0x7CC2,0xE2F1, // + 0x7CC5,0xE2F0, // + 0x7CCA,0x8CD0, // + 0x7CCE,0x9157, // + 0x7CD2,0xE2F3, // + 0x7CD6,0x939C, // + 0x7CD8,0xE2F2, // + 0x7CDC,0xE2F4, // + 0x7CDE,0x95B3, // + 0x7CDF,0x918C, // + 0x7CE0,0x8D66, // + 0x7CE2,0xE2F5, // + 0x7CE7,0x97C6, // + 0x7CEF,0xE2F7, // + 0x7CF2,0xE2F8, // + 0x7CF4,0xE2F9, // + 0x7CF6,0xE2FA, // + 0x7CF8,0x8E85, // + 0x7CFA,0xE2FB, // + 0x7CFB,0x8C6E, // + 0x7CFE,0x8B8A, // + 0x7D00,0x8B49, // + 0x7D02,0xE340, // + 0x7D04,0x96F1, // + 0x7D05,0x8D67, // + 0x7D06,0xE2FC, // + 0x7D0A,0xE343, // + 0x7D0B,0x96E4, // + 0x7D10,0x9552, // + 0x7D14,0x8F83, // + 0x7D15,0xE342, // + 0x7D17,0x8ED1, // + 0x7D18,0x8D68, // + 0x7D19,0x8E86, // + 0x7D1A,0x8B89, // + 0x7D1B,0x95B4, // + 0x7D1C,0xE341, // + 0x7D20,0x9166, // + 0x7D21,0x9661, // + 0x7D22,0x8DF5, // + 0x7D2B,0x8E87, // + 0x7D2C,0x92DB, // + 0x7D2E,0xE346, // + 0x7D2F,0x97DD, // + 0x7D30,0x8DD7, // + 0x7D32,0xE347, // + 0x7D33,0x9061, // + 0x7D35,0xE349, // + 0x7D39,0x8FD0, // + 0x7D3A,0x8DAE, // + 0x7D3F,0xE348, // + 0x7D42,0x8F49, // + 0x7D43,0x8CBC, // + 0x7D44,0x9167, // + 0x7D45,0xE344, // + 0x7D46,0xE34A, // + 0x7D4B,0xE345, // + 0x7D4C,0x8C6F, // + 0x7D4E,0xE34D, // + 0x7D4F,0xE351, // + 0x7D50,0x8C8B, // + 0x7D56,0xE34C, // + 0x7D5B,0xE355, // + 0x7D5E,0x8D69, // + 0x7D61,0x978D, // + 0x7D62,0x88BA, // + 0x7D63,0xE352, // + 0x7D66,0x8B8B, // + 0x7D68,0xE34F, // + 0x7D6E,0xE350, // + 0x7D71,0x939D, // + 0x7D72,0xE34E, // + 0x7D73,0xE34B, // + 0x7D75,0x8A47, // + 0x7D76,0x90E2, // + 0x7D79,0x8CA6, // + 0x7D7D,0xE357, // + 0x7D89,0xE354, // + 0x7D8F,0xE356, // + 0x7D93,0xE353, // + 0x7D99,0x8C70, // + 0x7D9A,0x91B1, // + 0x7D9B,0xE358, // + 0x7D9C,0x918E, // + 0x7D9F,0xE365, // + 0x7DA2,0xE361, // + 0x7DAB,0xE35F, // + 0x7DAC,0x8EF8, // + 0x7DAD,0x88DB, // + 0x7DAE,0xE35A, // + 0x7DAF,0xE362, // + 0x7DB0,0xE366, // + 0x7DB1,0x8D6A, // + 0x7DB2,0x96D4, // + 0x7DB4,0x92D4, // + 0x7DB5,0xE35C, // + 0x7DB8,0xE364, // + 0x7DBA,0xE359, // + 0x7DBB,0x925D, // + 0x7DBD,0xE35E, // + 0x7DBE,0x88BB, // + 0x7DBF,0x96C8, // + 0x7DC7,0xE35D, // + 0x7DCA,0x8BD9, // + 0x7DCB,0x94EA, // + 0x7DCF,0x918D, // + 0x7DD1,0x97CE, // + 0x7DD2,0x8F8F, // + 0x7DD5,0xE38E, // + 0x7DD8,0xE367, // + 0x7DDA,0x90FC, // + 0x7DDC,0xE363, // + 0x7DDD,0xE368, // + 0x7DDE,0xE36A, // + 0x7DE0,0x92F7, // + 0x7DE1,0xE36D, // + 0x7DE4,0xE369, // + 0x7DE8,0x95D2, // + 0x7DE9,0x8AC9, // + 0x7DEC,0x96C9, // + 0x7DEF,0x88DC, // + 0x7DF2,0xE36C, // + 0x7DF4,0x97FB, // + 0x7DFB,0xE36B, // + 0x7E01,0x898F, // + 0x7E04,0x93EA, // + 0x7E05,0xE36E, // + 0x7E09,0xE375, // + 0x7E0A,0xE36F, // + 0x7E0B,0xE376, // + 0x7E12,0xE372, // + 0x7E1B,0x949B, // + 0x7E1E,0x8EC8, // + 0x7E1F,0xE374, // + 0x7E21,0xE371, // + 0x7E22,0xE377, // + 0x7E23,0xE370, // + 0x7E26,0x8F63, // + 0x7E2B,0x9644, // + 0x7E2E,0x8F6B, // + 0x7E31,0xE373, // + 0x7E32,0xE380, // + 0x7E35,0xE37B, // + 0x7E37,0xE37E, // + 0x7E39,0xE37C, // + 0x7E3A,0xE381, // + 0x7E3B,0xE37A, // + 0x7E3D,0xE360, // + 0x7E3E,0x90D1, // + 0x7E41,0x94C9, // + 0x7E43,0xE37D, // + 0x7E46,0xE378, // + 0x7E4A,0x9140, // + 0x7E4B,0x8C71, // + 0x7E4D,0x8F4A, // + 0x7E54,0x9044, // + 0x7E55,0x9155, // + 0x7E56,0xE384, // + 0x7E59,0xE386, // + 0x7E5A,0xE387, // + 0x7E5D,0xE383, // + 0x7E5E,0xE385, // + 0x7E66,0xE379, // + 0x7E67,0xE382, // + 0x7E69,0xE38A, // + 0x7E6A,0xE389, // + 0x7E6D,0x969A, // + 0x7E70,0x8C4A, // + 0x7E79,0xE388, // + 0x7E7B,0xE38C, // + 0x7E7C,0xE38B, // + 0x7E7D,0xE38F, // + 0x7E7F,0xE391, // + 0x7E83,0xE38D, // + 0x7E88,0xE392, // + 0x7E89,0xE393, // + 0x7E8C,0xE394, // + 0x7E8E,0xE39A, // + 0x7E8F,0x935A, // + 0x7E90,0xE396, // + 0x7E92,0xE395, // + 0x7E93,0xE397, // + 0x7E94,0xE398, // + 0x7E96,0xE399, // + 0x7E9B,0xE39B, // + 0x7E9C,0xE39C, // + 0x7F36,0x8ACA, // + 0x7F38,0xE39D, // + 0x7F3A,0xE39E, // + 0x7F45,0xE39F, // + 0x7F4C,0xE3A0, // + 0x7F4D,0xE3A1, // + 0x7F4E,0xE3A2, // + 0x7F50,0xE3A3, // + 0x7F51,0xE3A4, // + 0x7F54,0xE3A6, // + 0x7F55,0xE3A5, // + 0x7F58,0xE3A7, // + 0x7F5F,0xE3A8, // + 0x7F60,0xE3A9, // + 0x7F67,0xE3AC, // + 0x7F68,0xE3AA, // + 0x7F69,0xE3AB, // + 0x7F6A,0x8DDF, // + 0x7F6B,0x8C72, // + 0x7F6E,0x9275, // + 0x7F70,0x94B1, // + 0x7F72,0x8F90, // + 0x7F75,0x946C, // + 0x7F77,0x94EB, // + 0x7F78,0xE3AD, // + 0x7F79,0x9CEB, // + 0x7F82,0xE3AE, // + 0x7F83,0xE3B0, // + 0x7F85,0x9785, // + 0x7F86,0xE3AF, // + 0x7F87,0xE3B2, // + 0x7F88,0xE3B1, // + 0x7F8A,0x9772, // + 0x7F8C,0xE3B3, // + 0x7F8E,0x94FC, // + 0x7F94,0xE3B4, // + 0x7F9A,0xE3B7, // + 0x7F9D,0xE3B6, // + 0x7F9E,0xE3B5, // + 0x7FA3,0xE3B8, // + 0x7FA4,0x8C51, // + 0x7FA8,0x9141, // + 0x7FA9,0x8B60, // + 0x7FAE,0xE3BC, // + 0x7FAF,0xE3B9, // + 0x7FB2,0xE3BA, // + 0x7FB6,0xE3BD, // + 0x7FB8,0xE3BE, // + 0x7FB9,0xE3BB, // + 0x7FBD,0x8948, // + 0x7FC1,0x89A5, // + 0x7FC5,0xE3C0, // + 0x7FC6,0xE3C1, // + 0x7FCA,0xE3C2, // + 0x7FCC,0x9782, // + 0x7FD2,0x8F4B, // + 0x7FD4,0xE3C4, // + 0x7FD5,0xE3C3, // + 0x7FE0,0x9089, // + 0x7FE1,0xE3C5, // + 0x7FE6,0xE3C6, // + 0x7FE9,0xE3C7, // + 0x7FEB,0x8AE3, // + 0x7FF0,0x8ACB, // + 0x7FF3,0xE3C8, // + 0x7FF9,0xE3C9, // + 0x7FFB,0x967C, // + 0x7FFC,0x9783, // + 0x8000,0x9773, // + 0x8001,0x9856, // + 0x8003,0x8D6C, // + 0x8004,0xE3CC, // + 0x8005,0x8ED2, // + 0x8006,0xE3CB, // + 0x800B,0xE3CD, // + 0x800C,0x8EA7, // + 0x8010,0x91CF, // + 0x8012,0xE3CE, // + 0x8015,0x8D6B, // + 0x8017,0x96D5, // + 0x8018,0xE3CF, // + 0x8019,0xE3D0, // + 0x801C,0xE3D1, // + 0x8021,0xE3D2, // + 0x8028,0xE3D3, // + 0x8033,0x8EA8, // + 0x8036,0x96EB, // + 0x803B,0xE3D5, // + 0x803D,0x925E, // + 0x803F,0xE3D4, // + 0x8046,0xE3D7, // + 0x804A,0xE3D6, // + 0x8052,0xE3D8, // + 0x8056,0x90B9, // + 0x8058,0xE3D9, // + 0x805A,0xE3DA, // + 0x805E,0x95B7, // + 0x805F,0xE3DB, // + 0x8061,0x918F, // + 0x8062,0xE3DC, // + 0x8068,0xE3DD, // + 0x806F,0x97FC, // + 0x8070,0xE3E0, // + 0x8072,0xE3DF, // + 0x8073,0xE3DE, // + 0x8074,0x92AE, // + 0x8076,0xE3E1, // + 0x8077,0x9045, // + 0x8079,0xE3E2, // + 0x807D,0xE3E3, // + 0x807E,0x9857, // + 0x807F,0xE3E4, // + 0x8084,0xE3E5, // + 0x8085,0xE3E7, // + 0x8086,0xE3E6, // + 0x8087,0x94A3, // + 0x8089,0x93F7, // + 0x808B,0x985D, // + 0x808C,0x94A7, // + 0x8093,0xE3E9, // + 0x8096,0x8FD1, // + 0x8098,0x9549, // + 0x809A,0xE3EA, // + 0x809B,0xE3E8, // + 0x809D,0x8ACC, // + 0x80A1,0x8CD2, // + 0x80A2,0x8E88, // + 0x80A5,0x94EC, // + 0x80A9,0x8CA8, // + 0x80AA,0x9662, // + 0x80AC,0xE3ED, // + 0x80AD,0xE3EB, // + 0x80AF,0x8D6D, // + 0x80B1,0x8D6E, // + 0x80B2,0x88E7, // + 0x80B4,0x8DE6, // + 0x80BA,0x9478, // + 0x80C3,0x88DD, // + 0x80C4,0xE3F2, // + 0x80C6,0x925F, // + 0x80CC,0x9477, // + 0x80CE,0x91D9, // + 0x80D6,0xE3F4, // + 0x80D9,0xE3F0, // + 0x80DA,0xE3F3, // + 0x80DB,0xE3EE, // + 0x80DD,0xE3F1, // + 0x80DE,0x9645, // + 0x80E1,0x8CD3, // + 0x80E4,0x88FB, // + 0x80E5,0xE3EF, // + 0x80EF,0xE3F6, // + 0x80F1,0xE3F7, // + 0x80F4,0x93B7, // + 0x80F8,0x8BB9, // + 0x80FC,0xE445, // + 0x80FD,0x945C, // + 0x8102,0x8E89, // + 0x8105,0x8BBA, // + 0x8106,0x90C6, // + 0x8107,0x9865, // + 0x8108,0x96AC, // + 0x8109,0xE3F5, // + 0x810A,0x90D2, // + 0x811A,0x8B72, // + 0x811B,0xE3F8, // + 0x8123,0xE3FA, // + 0x8129,0xE3F9, // + 0x812F,0xE3FB, // + 0x8131,0x9245, // + 0x8133,0x945D, // + 0x8139,0x92AF, // + 0x813E,0xE442, // + 0x8146,0xE441, // + 0x814B,0xE3FC, // + 0x814E,0x9074, // + 0x8150,0x9585, // + 0x8151,0xE444, // + 0x8153,0xE443, // + 0x8154,0x8D6F, // + 0x8155,0x9872, // + 0x815F,0xE454, // + 0x8165,0xE448, // + 0x8166,0xE449, // + 0x816B,0x8EEE, // + 0x816E,0xE447, // + 0x8170,0x8D98, // + 0x8171,0xE446, // + 0x8174,0xE44A, // + 0x8178,0x92B0, // + 0x8179,0x95A0, // + 0x817A,0x9142, // + 0x817F,0x91DA, // + 0x8180,0xE44E, // + 0x8182,0xE44F, // + 0x8183,0xE44B, // + 0x8188,0xE44C, // + 0x818A,0xE44D, // + 0x818F,0x8D70, // + 0x8193,0xE455, // + 0x8195,0xE451, // + 0x819A,0x9586, // + 0x819C,0x968C, // + 0x819D,0x9547, // + 0x81A0,0xE450, // + 0x81A3,0xE453, // + 0x81A4,0xE452, // + 0x81A8,0x9663, // + 0x81A9,0xE456, // + 0x81B0,0xE457, // + 0x81B3,0x9156, // + 0x81B5,0xE458, // + 0x81B8,0xE45A, // + 0x81BA,0xE45E, // + 0x81BE,0xE459, // + 0x81BF,0x945E, // + 0x81C0,0xE45C, // + 0x81C2,0xE45D, // + 0x81C6,0x89B0, // + 0x81C8,0xE464, // + 0x81C9,0xE45F, // + 0x81CD,0xE460, // + 0x81D1,0xE461, // + 0x81D3,0x919F, // + 0x81D8,0xE463, // + 0x81D9,0xE462, // + 0x81DA,0xE465, // + 0x81DF,0xE466, // + 0x81E0,0xE467, // + 0x81E3,0x9062, // + 0x81E5,0x89E7, // + 0x81E7,0xE468, // + 0x81E8,0x97D5, // + 0x81EA,0x8EA9, // + 0x81ED,0x8F4C, // + 0x81F3,0x8E8A, // + 0x81F4,0x9276, // + 0x81FA,0xE469, // + 0x81FB,0xE46A, // + 0x81FC,0x8950, // + 0x81FE,0xE46B, // + 0x8201,0xE46C, // + 0x8202,0xE46D, // + 0x8205,0xE46E, // + 0x8207,0xE46F, // + 0x8208,0x8BBB, // + 0x8209,0x9DA8, // + 0x820A,0xE470, // + 0x820C,0x90E3, // + 0x820D,0xE471, // + 0x820E,0x8EC9, // + 0x8210,0xE472, // + 0x8212,0x98AE, // + 0x8216,0xE473, // + 0x8217,0x95DC, // + 0x8218,0x8ADA, // + 0x821B,0x9143, // + 0x821C,0x8F77, // + 0x821E,0x9591, // + 0x821F,0x8F4D, // + 0x8229,0xE474, // + 0x822A,0x8D71, // + 0x822B,0xE475, // + 0x822C,0x94CA, // + 0x822E,0xE484, // + 0x8233,0xE477, // + 0x8235,0x91C7, // + 0x8236,0x9495, // + 0x8237,0x8CBD, // + 0x8238,0xE476, // + 0x8239,0x9144, // + 0x8240,0xE478, // + 0x8247,0x92F8, // + 0x8258,0xE47A, // + 0x8259,0xE479, // + 0x825A,0xE47C, // + 0x825D,0xE47B, // + 0x825F,0xE47D, // + 0x8262,0xE480, // + 0x8264,0xE47E, // + 0x8266,0x8ACD, // + 0x8268,0xE481, // + 0x826A,0xE482, // + 0x826B,0xE483, // + 0x826E,0x8DAF, // + 0x826F,0x97C7, // + 0x8271,0xE485, // + 0x8272,0x9046, // + 0x8276,0x8990, // + 0x8277,0xE486, // + 0x8278,0xE487, // + 0x827E,0xE488, // + 0x828B,0x88F0, // + 0x828D,0xE489, // + 0x8292,0xE48A, // + 0x8299,0x9587, // + 0x829D,0x8EC5, // + 0x829F,0xE48C, // + 0x82A5,0x8A48, // + 0x82A6,0x88B0, // + 0x82AB,0xE48B, // + 0x82AC,0xE48E, // + 0x82AD,0x946D, // + 0x82AF,0x9063, // + 0x82B1,0x89D4, // + 0x82B3,0x9646, // + 0x82B8,0x8C7C, // + 0x82B9,0x8BDA, // + 0x82BB,0xE48D, // + 0x82BD,0x89E8, // + 0x82C5,0x8AA1, // + 0x82D1,0x8991, // + 0x82D2,0xE492, // + 0x82D3,0x97E8, // + 0x82D4,0x91DB, // + 0x82D7,0x9563, // + 0x82D9,0xE49E, // + 0x82DB,0x89D5, // + 0x82DC,0xE49C, // + 0x82DE,0xE49A, // + 0x82DF,0xE491, // + 0x82E1,0xE48F, // + 0x82E3,0xE490, // + 0x82E5,0x8EE1, // + 0x82E6,0x8BEA, // + 0x82E7,0x9297, // + 0x82EB,0x93CF, // + 0x82F1,0x8970, // + 0x82F3,0xE494, // + 0x82F4,0xE493, // + 0x82F9,0xE499, // + 0x82FA,0xE495, // + 0x82FB,0xE498, // + 0x8302,0x96CE, // + 0x8303,0xE497, // + 0x8304,0x89D6, // + 0x8305,0x8A9D, // + 0x8306,0xE49B, // + 0x8309,0xE49D, // + 0x830E,0x8C73, // + 0x8316,0xE4A1, // + 0x8317,0xE4AA, // + 0x8318,0xE4AB, // + 0x831C,0x88A9, // + 0x8323,0xE4B2, // + 0x8328,0x88EF, // + 0x832B,0xE4A9, // + 0x832F,0xE4A8, // + 0x8331,0xE4A3, // + 0x8332,0xE4A2, // + 0x8334,0xE4A0, // + 0x8335,0xE49F, // + 0x8336,0x9283, // + 0x8338,0x91F9, // + 0x8339,0xE4A5, // + 0x8340,0xE4A4, // + 0x8345,0xE4A7, // + 0x8349,0x9190, // + 0x834A,0x8C74, // + 0x834F,0x8960, // + 0x8350,0xE4A6, // + 0x8352,0x8D72, // + 0x8358,0x9191, // + 0x8373,0xE4B8, // + 0x8375,0xE4B9, // + 0x8377,0x89D7, // + 0x837B,0x89AC, // + 0x837C,0xE4B6, // + 0x8385,0xE4AC, // + 0x8387,0xE4B4, // + 0x8389,0xE4BB, // + 0x838A,0xE4B5, // + 0x838E,0xE4B3, // + 0x8393,0xE496, // + 0x8396,0xE4B1, // + 0x839A,0xE4AD, // + 0x839E,0x8ACE, // + 0x839F,0xE4AF, // + 0x83A0,0xE4BA, // + 0x83A2,0xE4B0, // + 0x83A8,0xE4BC, // + 0x83AA,0xE4AE, // + 0x83AB,0x949C, // + 0x83B1,0x9789, // + 0x83B5,0xE4B7, // + 0x83BD,0xE4CD, // + 0x83C1,0xE4C5, // + 0x83C5,0x909B, // + 0x83CA,0x8B65, // + 0x83CC,0x8BDB, // + 0x83CE,0xE4C0, // + 0x83D3,0x89D9, // + 0x83D6,0x8FD2, // + 0x83D8,0xE4C3, // + 0x83DC,0x8DD8, // + 0x83DF,0x9370, // + 0x83E0,0xE4C8, // + 0x83E9,0x95EC, // + 0x83EB,0xE4BF, // + 0x83EF,0x89D8, // + 0x83F0,0x8CD4, // + 0x83F1,0x9548, // + 0x83F2,0xE4C9, // + 0x83F4,0xE4BD, // + 0x83F7,0xE4C6, // + 0x83FB,0xE4D0, // + 0x83FD,0xE4C1, // + 0x8403,0xE4C2, // + 0x8404,0x93B8, // + 0x8407,0xE4C7, // + 0x840B,0xE4C4, // + 0x840C,0x9647, // + 0x840D,0xE4CA, // + 0x840E,0x88DE, // + 0x8413,0xE4BE, // + 0x8420,0xE4CC, // + 0x8422,0xE4CB, // + 0x8429,0x948B, // + 0x842A,0xE4D2, // + 0x842C,0xE4DD, // + 0x8431,0x8A9E, // + 0x8435,0xE4E0, // + 0x8438,0xE4CE, // + 0x843C,0xE4D3, // + 0x843D,0x978E, // + 0x8446,0xE4DC, // + 0x8449,0x9774, // + 0x844E,0x97A8, // + 0x8457,0x9298, // + 0x845B,0x8A8B, // + 0x8461,0x9592, // + 0x8462,0xE4E2, // + 0x8463,0x939F, // + 0x8466,0x88AF, // + 0x8469,0xE4DB, // + 0x846B,0xE4D7, // + 0x846C,0x9192, // + 0x846D,0xE4D1, // + 0x846E,0xE4D9, // + 0x846F,0xE4DE, // + 0x8471,0x944B, // + 0x8475,0x88A8, // + 0x8477,0xE4D6, // + 0x8479,0xE4DF, // + 0x847A,0x9598, // + 0x8482,0xE4DA, // + 0x8484,0xE4D5, // + 0x848B,0x8FD3, // + 0x8490,0x8F4E, // + 0x8494,0x8EAA, // + 0x8499,0x96D6, // + 0x849C,0x9566, // + 0x849F,0xE4E5, // + 0x84A1,0xE4EE, // + 0x84AD,0xE4D8, // + 0x84B2,0x8A97, // + 0x84B8,0x8FF6, // + 0x84B9,0xE4E3, // + 0x84BB,0xE4E8, // + 0x84BC,0x9193, // + 0x84BF,0xE4E4, // + 0x84C1,0xE4EB, // + 0x84C4,0x927E, // + 0x84C6,0xE4EC, // + 0x84C9,0x9775, // + 0x84CA,0xE4E1, // + 0x84CB,0x8A57, // + 0x84CD,0xE4E7, // + 0x84D0,0xE4EA, // + 0x84D1,0x96AA, // + 0x84D6,0xE4ED, // + 0x84D9,0xE4E6, // + 0x84DA,0xE4E9, // + 0x84EC,0x9648, // + 0x84EE,0x9840, // + 0x84F4,0xE4F1, // + 0x84FC,0xE4F8, // + 0x84FF,0xE4F0, // + 0x8500,0x8EC1, // + 0x8506,0xE4CF, // + 0x8511,0x95CC, // + 0x8513,0x96A0, // + 0x8514,0xE4F7, // + 0x8515,0xE4F6, // + 0x8517,0xE4F2, // + 0x8518,0xE4F3, // + 0x851A,0x8955, // + 0x851F,0xE4F5, // + 0x8521,0xE4EF, // + 0x8526,0x92D3, // + 0x852C,0xE4F4, // + 0x852D,0x88FC, // + 0x8535,0x91A0, // + 0x853D,0x95C1, // + 0x8540,0xE4F9, // + 0x8541,0xE540, // + 0x8543,0x94D7, // + 0x8548,0xE4FC, // + 0x8549,0x8FD4, // + 0x854A,0x8EC7, // + 0x854B,0xE542, // + 0x854E,0x8BBC, // + 0x8555,0xE543, // + 0x8557,0x9599, // + 0x8558,0xE4FB, // + 0x855A,0xE4D4, // + 0x8563,0xE4FA, // + 0x8568,0x986E, // + 0x8569,0x93A0, // + 0x856A,0x9593, // + 0x856D,0xE54A, // + 0x8577,0xE550, // + 0x857E,0xE551, // + 0x8580,0xE544, // + 0x8584,0x9496, // + 0x8587,0xE54E, // + 0x8588,0xE546, // + 0x858A,0xE548, // + 0x8590,0xE552, // + 0x8591,0xE547, // + 0x8594,0xE54B, // + 0x8597,0x8992, // + 0x8599,0x93E3, // + 0x859B,0xE54C, // + 0x859C,0xE54F, // + 0x85A4,0xE545, // + 0x85A6,0x9145, // + 0x85A8,0xE549, // + 0x85A9,0x8E46, // + 0x85AA,0x9064, // + 0x85AB,0x8C4F, // + 0x85AC,0x96F2, // + 0x85AE,0x96F7, // + 0x85AF,0x8F92, // + 0x85B9,0xE556, // + 0x85BA,0xE554, // + 0x85C1,0x986D, // + 0x85C9,0xE553, // + 0x85CD,0x9795, // + 0x85CF,0xE555, // + 0x85D0,0xE557, // + 0x85D5,0xE558, // + 0x85DD,0xE559, // + 0x85E4,0x93A1, // + 0x85E5,0xE55A, // + 0x85E9,0x94CB, // + 0x85EA,0xE54D, // + 0x85F7,0x8F93, // + 0x85F9,0xE55C, // + 0x85FA,0xE561, // + 0x85FB,0x9194, // + 0x85FE,0xE560, // + 0x8602,0xE541, // + 0x8606,0xE562, // + 0x8607,0x9168, // + 0x860A,0xE55D, // + 0x860B,0xE55F, // + 0x8613,0xE55E, // + 0x8616,0x9F50, // + 0x8617,0x9F41, // + 0x861A,0xE564, // + 0x8622,0xE563, // + 0x862D,0x9796, // + 0x862F,0xE1BA, // + 0x8630,0xE565, // + 0x863F,0xE566, // + 0x864D,0xE567, // + 0x864E,0x8CD5, // + 0x8650,0x8B73, // + 0x8654,0xE569, // + 0x8655,0x997C, // + 0x865A,0x8B95, // + 0x865C,0x97B8, // + 0x865E,0x8BF1, // + 0x865F,0xE56A, // + 0x8667,0xE56B, // + 0x866B,0x928E, // + 0x8671,0xE56C, // + 0x8679,0x93F8, // + 0x867B,0x88B8, // + 0x868A,0x89E1, // + 0x868B,0xE571, // + 0x868C,0xE572, // + 0x8693,0xE56D, // + 0x8695,0x8E5C, // + 0x86A3,0xE56E, // + 0x86A4,0x9461, // + 0x86A9,0xE56F, // + 0x86AA,0xE570, // + 0x86AB,0xE57A, // + 0x86AF,0xE574, // + 0x86B0,0xE577, // + 0x86B6,0xE573, // + 0x86C4,0xE575, // + 0x86C6,0xE576, // + 0x86C7,0x8ED6, // + 0x86C9,0xE578, // + 0x86CB,0x9260, // + 0x86CD,0x8C75, // + 0x86CE,0x8A61, // + 0x86D4,0xE57B, // + 0x86D9,0x8A5E, // + 0x86DB,0xE581, // + 0x86DE,0xE57C, // + 0x86DF,0xE580, // + 0x86E4,0x94B8, // + 0x86E9,0xE57D, // + 0x86EC,0xE57E, // + 0x86ED,0x9567, // + 0x86EE,0x94D8, // + 0x86EF,0xE582, // + 0x86F8,0x91FB, // + 0x86F9,0xE58C, // + 0x86FB,0xE588, // + 0x86FE,0x89E9, // + 0x8700,0xE586, // + 0x8702,0x9649, // + 0x8703,0xE587, // + 0x8706,0xE584, // + 0x8708,0xE585, // + 0x8709,0xE58A, // + 0x870A,0xE58D, // + 0x870D,0xE58B, // + 0x8711,0xE589, // + 0x8712,0xE583, // + 0x8718,0x9277, // + 0x871A,0xE594, // + 0x871C,0x96A8, // + 0x8725,0xE592, // + 0x8729,0xE593, // + 0x8734,0xE58E, // + 0x8737,0xE590, // + 0x873B,0xE591, // + 0x873F,0xE58F, // + 0x8749,0x90E4, // + 0x874B,0x9858, // + 0x874C,0xE598, // + 0x874E,0xE599, // + 0x8753,0xE59F, // + 0x8755,0x9049, // + 0x8757,0xE59B, // + 0x8759,0xE59E, // + 0x875F,0xE596, // + 0x8760,0xE595, // + 0x8763,0xE5A0, // + 0x8766,0x89DA, // + 0x8768,0xE59C, // + 0x876A,0xE5A1, // + 0x876E,0xE59D, // + 0x8774,0xE59A, // + 0x8776,0x92B1, // + 0x8778,0xE597, // + 0x877F,0x9488, // + 0x8782,0xE5A5, // + 0x878D,0x975A, // + 0x879F,0xE5A4, // + 0x87A2,0xE5A3, // + 0x87AB,0xE5AC, // + 0x87AF,0xE5A6, // + 0x87B3,0xE5AE, // + 0x87BA,0x9786, // + 0x87BB,0xE5B1, // + 0x87BD,0xE5A8, // + 0x87C0,0xE5A9, // + 0x87C4,0xE5AD, // + 0x87C6,0xE5B0, // + 0x87C7,0xE5AF, // + 0x87CB,0xE5A7, // + 0x87D0,0xE5AA, // + 0x87D2,0xE5BB, // + 0x87E0,0xE5B4, // + 0x87EF,0xE5B2, // + 0x87F2,0xE5B3, // + 0x87F6,0xE5B8, // + 0x87F7,0xE5B9, // + 0x87F9,0x8A49, // + 0x87FB,0x8B61, // + 0x87FE,0xE5B7, // + 0x8805,0xE5A2, // + 0x880D,0xE5B6, // + 0x880E,0xE5BA, // + 0x880F,0xE5B5, // + 0x8811,0xE5BC, // + 0x8815,0xE5BE, // + 0x8816,0xE5BD, // + 0x8821,0xE5C0, // + 0x8822,0xE5BF, // + 0x8823,0xE579, // + 0x8827,0xE5C4, // + 0x8831,0xE5C1, // + 0x8836,0xE5C2, // + 0x8839,0xE5C3, // + 0x883B,0xE5C5, // + 0x8840,0x8C8C, // + 0x8842,0xE5C7, // + 0x8844,0xE5C6, // + 0x8846,0x8F4F, // + 0x884C,0x8D73, // + 0x884D,0x9FA5, // + 0x8852,0xE5C8, // + 0x8853,0x8F70, // + 0x8857,0x8A58, // + 0x8859,0xE5C9, // + 0x885B,0x8971, // + 0x885D,0x8FD5, // + 0x885E,0xE5CA, // + 0x8861,0x8D74, // + 0x8862,0xE5CB, // + 0x8863,0x88DF, // + 0x8868,0x955C, // + 0x886B,0xE5CC, // + 0x8870,0x908A, // + 0x8872,0xE5D3, // + 0x8875,0xE5D0, // + 0x8877,0x928F, // + 0x887D,0xE5D1, // + 0x887E,0xE5CE, // + 0x887F,0x8BDC, // + 0x8881,0xE5CD, // + 0x8882,0xE5D4, // + 0x8888,0x8C55, // + 0x888B,0x91DC, // + 0x888D,0xE5DA, // + 0x8892,0xE5D6, // + 0x8896,0x91B3, // + 0x8897,0xE5D5, // + 0x8899,0xE5D8, // + 0x889E,0xE5CF, // + 0x88A2,0xE5D9, // + 0x88A4,0xE5DB, // + 0x88AB,0x94ED, // + 0x88AE,0xE5D7, // + 0x88B0,0xE5DC, // + 0x88B1,0xE5DE, // + 0x88B4,0x8CD1, // + 0x88B5,0xE5D2, // + 0x88B7,0x88BF, // + 0x88BF,0xE5DD, // + 0x88C1,0x8DD9, // + 0x88C2,0x97F4, // + 0x88C3,0xE5DF, // + 0x88C4,0xE5E0, // + 0x88C5,0x9195, // + 0x88CF,0x97A0, // + 0x88D4,0xE5E1, // + 0x88D5,0x9754, // + 0x88D8,0xE5E2, // + 0x88D9,0xE5E3, // + 0x88DC,0x95E2, // + 0x88DD,0xE5E4, // + 0x88DF,0x8DBE, // + 0x88E1,0x97A1, // + 0x88E8,0xE5E9, // + 0x88F2,0xE5EA, // + 0x88F3,0x8FD6, // + 0x88F4,0xE5E8, // + 0x88F8,0x9787, // + 0x88F9,0xE5E5, // + 0x88FC,0xE5E7, // + 0x88FD,0x90BB, // + 0x88FE,0x909E, // + 0x8902,0xE5E6, // + 0x8904,0xE5EB, // + 0x8907,0x95A1, // + 0x890A,0xE5ED, // + 0x890C,0xE5EC, // + 0x8910,0x8A8C, // + 0x8912,0x964A, // + 0x8913,0xE5EE, // + 0x891D,0xE5FA, // + 0x891E,0xE5F0, // + 0x8925,0xE5F1, // + 0x892A,0xE5F2, // + 0x892B,0xE5F3, // + 0x8936,0xE5F7, // + 0x8938,0xE5F8, // + 0x893B,0xE5F6, // + 0x8941,0xE5F4, // + 0x8943,0xE5EF, // + 0x8944,0xE5F5, // + 0x894C,0xE5F9, // + 0x894D,0xE8B5, // + 0x8956,0x89A6, // + 0x895E,0xE5FC, // + 0x895F,0x8BDD, // + 0x8960,0xE5FB, // + 0x8964,0xE641, // + 0x8966,0xE640, // + 0x896A,0xE643, // + 0x896D,0xE642, // + 0x896F,0xE644, // + 0x8972,0x8F50, // + 0x8974,0xE645, // + 0x8977,0xE646, // + 0x897E,0xE647, // + 0x897F,0x90BC, // + 0x8981,0x9776, // + 0x8983,0xE648, // + 0x8986,0x95A2, // + 0x8987,0x9465, // + 0x8988,0xE649, // + 0x898A,0xE64A, // + 0x898B,0x8CA9, // + 0x898F,0x8B4B, // + 0x8993,0xE64B, // + 0x8996,0x8E8B, // + 0x8997,0x9460, // + 0x8998,0xE64C, // + 0x899A,0x8A6F, // + 0x89A1,0xE64D, // + 0x89A6,0xE64F, // + 0x89A7,0x9797, // + 0x89A9,0xE64E, // + 0x89AA,0x9065, // + 0x89AC,0xE650, // + 0x89AF,0xE651, // + 0x89B2,0xE652, // + 0x89B3,0x8ACF, // + 0x89BA,0xE653, // + 0x89BD,0xE654, // + 0x89BF,0xE655, // + 0x89C0,0xE656, // + 0x89D2,0x8A70, // + 0x89DA,0xE657, // + 0x89DC,0xE658, // + 0x89DD,0xE659, // + 0x89E3,0x89F0, // + 0x89E6,0x9047, // + 0x89E7,0xE65A, // + 0x89F8,0xE65C, // + 0x8A00,0x8CBE, // + 0x8A02,0x92F9, // + 0x8A03,0xE65D, // + 0x8A08,0x8C76, // + 0x8A0A,0x9075, // + 0x8A0C,0xE660, // + 0x8A0E,0x93A2, // + 0x8A10,0xE65F, // + 0x8A13,0x8C50, // + 0x8A16,0xE65E, // + 0x8A17,0x91F5, // + 0x8A18,0x8B4C, // + 0x8A1B,0xE661, // + 0x8A1D,0xE662, // + 0x8A1F,0x8FD7, // + 0x8A23,0x8C8D, // + 0x8A25,0xE663, // + 0x8A2A,0x964B, // + 0x8A2D,0x90DD, // + 0x8A31,0x8B96, // + 0x8A33,0x96F3, // + 0x8A34,0x9169, // + 0x8A36,0xE664, // + 0x8A3A,0x9066, // + 0x8A3B,0x9290, // + 0x8A3C,0x8FD8, // + 0x8A41,0xE665, // + 0x8A46,0xE668, // + 0x8A48,0xE669, // + 0x8A50,0x8DBC, // + 0x8A51,0x91C0, // + 0x8A52,0xE667, // + 0x8A54,0x8FD9, // + 0x8A55,0x955D, // + 0x8A5B,0xE666, // + 0x8A5E,0x8E8C, // + 0x8A60,0x8972, // + 0x8A62,0xE66D, // + 0x8A63,0x8C77, // + 0x8A66,0x8E8E, // + 0x8A69,0x8E8D, // + 0x8A6B,0x986C, // + 0x8A6C,0xE66C, // + 0x8A6D,0xE66B, // + 0x8A6E,0x9146, // + 0x8A70,0x8B6C, // + 0x8A71,0x9862, // + 0x8A72,0x8A59, // + 0x8A73,0x8FDA, // + 0x8A7C,0xE66A, // + 0x8A82,0xE66F, // + 0x8A84,0xE670, // + 0x8A85,0xE66E, // + 0x8A87,0x8CD6, // + 0x8A89,0x975F, // + 0x8A8C,0x8E8F, // + 0x8A8D,0x9446, // + 0x8A91,0xE673, // + 0x8A93,0x90BE, // + 0x8A95,0x9261, // + 0x8A98,0x9755, // + 0x8A9A,0xE676, // + 0x8A9E,0x8CEA, // + 0x8AA0,0x90BD, // + 0x8AA1,0xE672, // + 0x8AA3,0xE677, // + 0x8AA4,0x8CEB, // + 0x8AA5,0xE674, // + 0x8AA6,0xE675, // + 0x8AA8,0xE671, // + 0x8AAC,0x90E0, // + 0x8AAD,0x93C7, // + 0x8AB0,0x924E, // + 0x8AB2,0x89DB, // + 0x8AB9,0x94EE, // + 0x8ABC,0x8B62, // + 0x8ABF,0x92B2, // + 0x8AC2,0xE67A, // + 0x8AC4,0xE678, // + 0x8AC7,0x926B, // + 0x8ACB,0x90BF, // + 0x8ACC,0x8AD0, // + 0x8ACD,0xE679, // + 0x8ACF,0x907A, // + 0x8AD2,0x97C8, // + 0x8AD6,0x985F, // + 0x8ADA,0xE67B, // + 0x8ADB,0xE687, // + 0x8ADC,0x92B3, // + 0x8ADE,0xE686, // + 0x8AE0,0xE683, // + 0x8AE1,0xE68B, // + 0x8AE2,0xE684, // + 0x8AE4,0xE680, // + 0x8AE6,0x92FA, // + 0x8AE7,0xE67E, // + 0x8AEB,0xE67C, // + 0x8AED,0x9740, // + 0x8AEE,0x8E90, // + 0x8AF1,0xE681, // + 0x8AF3,0xE67D, // + 0x8AF7,0xE685, // + 0x8AF8,0x8F94, // + 0x8AFA,0x8CBF, // + 0x8AFE,0x91F8, // + 0x8B00,0x9664, // + 0x8B01,0x8979, // + 0x8B02,0x88E0, // + 0x8B04,0x93A3, // + 0x8B07,0xE689, // + 0x8B0C,0xE688, // + 0x8B0E,0x93E4, // + 0x8B10,0xE68D, // + 0x8B14,0xE682, // + 0x8B16,0xE68C, // + 0x8B17,0xE68E, // + 0x8B19,0x8CAA, // + 0x8B1A,0xE68A, // + 0x8B1B,0x8D75, // + 0x8B1D,0x8ED3, // + 0x8B20,0xE68F, // + 0x8B21,0x9777, // + 0x8B26,0xE692, // + 0x8B28,0xE695, // + 0x8B2B,0xE693, // + 0x8B2C,0x9554, // + 0x8B33,0xE690, // + 0x8B39,0x8BDE, // + 0x8B3E,0xE694, // + 0x8B41,0xE696, // + 0x8B49,0xE69A, // + 0x8B4C,0xE697, // + 0x8B4E,0xE699, // + 0x8B4F,0xE698, // + 0x8B56,0xE69B, // + 0x8B58,0x8EAF, // + 0x8B5A,0xE69D, // + 0x8B5B,0xE69C, // + 0x8B5C,0x9588, // + 0x8B5F,0xE69F, // + 0x8B66,0x8C78, // + 0x8B6B,0xE69E, // + 0x8B6C,0xE6A0, // + 0x8B6F,0xE6A1, // + 0x8B70,0x8B63, // + 0x8B71,0xE3BF, // + 0x8B72,0x8FF7, // + 0x8B74,0xE6A2, // + 0x8B77,0x8CEC, // + 0x8B7D,0xE6A3, // + 0x8B80,0xE6A4, // + 0x8B83,0x8E5D, // + 0x8B8A,0x9DCC, // + 0x8B8C,0xE6A5, // + 0x8B8E,0xE6A6, // + 0x8B90,0x8F51, // + 0x8B92,0xE6A7, // + 0x8B93,0xE6A8, // + 0x8B96,0xE6A9, // + 0x8B99,0xE6AA, // + 0x8B9A,0xE6AB, // + 0x8C37,0x924A, // + 0x8C3A,0xE6AC, // + 0x8C3F,0xE6AE, // + 0x8C41,0xE6AD, // + 0x8C46,0x93A4, // + 0x8C48,0xE6AF, // + 0x8C4A,0x964C, // + 0x8C4C,0xE6B0, // + 0x8C4E,0xE6B1, // + 0x8C50,0xE6B2, // + 0x8C55,0xE6B3, // + 0x8C5A,0x93D8, // + 0x8C61,0x8FDB, // + 0x8C62,0xE6B4, // + 0x8C6A,0x8D8B, // + 0x8C6B,0x98AC, // + 0x8C6C,0xE6B5, // + 0x8C78,0xE6B6, // + 0x8C79,0x955E, // + 0x8C7A,0xE6B7, // + 0x8C7C,0xE6BF, // + 0x8C82,0xE6B8, // + 0x8C85,0xE6BA, // + 0x8C89,0xE6B9, // + 0x8C8A,0xE6BB, // + 0x8C8C,0x9665, // + 0x8C8D,0xE6BC, // + 0x8C8E,0xE6BD, // + 0x8C94,0xE6BE, // + 0x8C98,0xE6C0, // + 0x8C9D,0x8A4C, // + 0x8C9E,0x92E5, // + 0x8CA0,0x9589, // + 0x8CA1,0x8DE0, // + 0x8CA2,0x8D76, // + 0x8CA7,0x956E, // + 0x8CA8,0x89DD, // + 0x8CA9,0x94CC, // + 0x8CAA,0xE6C3, // + 0x8CAB,0x8AD1, // + 0x8CAC,0x90D3, // + 0x8CAD,0xE6C2, // + 0x8CAE,0xE6C7, // + 0x8CAF,0x9299, // + 0x8CB0,0x96E1, // + 0x8CB2,0xE6C5, // + 0x8CB3,0xE6C6, // + 0x8CB4,0x8B4D, // + 0x8CB6,0xE6C8, // + 0x8CB7,0x9483, // + 0x8CB8,0x91DD, // + 0x8CBB,0x94EF, // + 0x8CBC,0x935C, // + 0x8CBD,0xE6C4, // + 0x8CBF,0x9666, // + 0x8CC0,0x89EA, // + 0x8CC1,0xE6CA, // + 0x8CC2,0x9847, // + 0x8CC3,0x92C0, // + 0x8CC4,0x9864, // + 0x8CC7,0x8E91, // + 0x8CC8,0xE6C9, // + 0x8CCA,0x91AF, // + 0x8CCD,0xE6DA, // + 0x8CCE,0x9147, // + 0x8CD1,0x93F6, // + 0x8CD3,0x956F, // + 0x8CDA,0xE6CD, // + 0x8CDB,0x8E5E, // + 0x8CDC,0x8E92, // + 0x8CDE,0x8FDC, // + 0x8CE0,0x9485, // + 0x8CE2,0x8CAB, // + 0x8CE3,0xE6CC, // + 0x8CE4,0xE6CB, // + 0x8CE6,0x958A, // + 0x8CEA,0x8EBF, // + 0x8CED,0x9371, // + 0x8CFA,0xE6CF, // + 0x8CFB,0xE6D0, // + 0x8CFC,0x8D77, // + 0x8CFD,0xE6CE, // + 0x8D04,0xE6D1, // + 0x8D05,0xE6D2, // + 0x8D07,0xE6D4, // + 0x8D08,0x91A1, // + 0x8D0A,0xE6D3, // + 0x8D0B,0x8AE4, // + 0x8D0D,0xE6D6, // + 0x8D0F,0xE6D5, // + 0x8D10,0xE6D7, // + 0x8D13,0xE6D9, // + 0x8D14,0xE6DB, // + 0x8D16,0xE6DC, // + 0x8D64,0x90D4, // + 0x8D66,0x8ECD, // + 0x8D67,0xE6DD, // + 0x8D6B,0x8A71, // + 0x8D6D,0xE6DE, // + 0x8D70,0x9196, // + 0x8D71,0xE6DF, // + 0x8D73,0xE6E0, // + 0x8D74,0x958B, // + 0x8D77,0x8B4E, // + 0x8D81,0xE6E1, // + 0x8D85,0x92B4, // + 0x8D8A,0x897A, // + 0x8D99,0xE6E2, // + 0x8DA3,0x8EEF, // + 0x8DA8,0x9096, // + 0x8DB3,0x91AB, // + 0x8DBA,0xE6E5, // + 0x8DBE,0xE6E4, // + 0x8DC2,0xE6E3, // + 0x8DCB,0xE6EB, // + 0x8DCC,0xE6E9, // + 0x8DCF,0xE6E6, // + 0x8DD6,0xE6E8, // + 0x8DDA,0xE6E7, // + 0x8DDB,0xE6EA, // + 0x8DDD,0x8B97, // + 0x8DDF,0xE6EE, // + 0x8DE1,0x90D5, // + 0x8DE3,0xE6EF, // + 0x8DE8,0x8CD7, // + 0x8DEA,0xE6EC, // + 0x8DEB,0xE6ED, // + 0x8DEF,0x9848, // + 0x8DF3,0x92B5, // + 0x8DF5,0x9148, // + 0x8DFC,0xE6F0, // + 0x8DFF,0xE6F3, // + 0x8E08,0xE6F1, // + 0x8E09,0xE6F2, // + 0x8E0A,0x9778, // + 0x8E0F,0x93A5, // + 0x8E10,0xE6F6, // + 0x8E1D,0xE6F4, // + 0x8E1E,0xE6F5, // + 0x8E1F,0xE6F7, // + 0x8E2A,0xE748, // + 0x8E30,0xE6FA, // + 0x8E34,0xE6FB, // + 0x8E35,0xE6F9, // + 0x8E42,0xE6F8, // + 0x8E44,0x92FB, // + 0x8E47,0xE740, // + 0x8E48,0xE744, // + 0x8E49,0xE741, // + 0x8E4A,0xE6FC, // + 0x8E4C,0xE742, // + 0x8E50,0xE743, // + 0x8E55,0xE74A, // + 0x8E59,0xE745, // + 0x8E5F,0x90D6, // + 0x8E60,0xE747, // + 0x8E63,0xE749, // + 0x8E64,0xE746, // + 0x8E72,0xE74C, // + 0x8E74,0x8F52, // + 0x8E76,0xE74B, // + 0x8E7C,0xE74D, // + 0x8E81,0xE74E, // + 0x8E84,0xE751, // + 0x8E85,0xE750, // + 0x8E87,0xE74F, // + 0x8E8A,0xE753, // + 0x8E8B,0xE752, // + 0x8E8D,0x96F4, // + 0x8E91,0xE755, // + 0x8E93,0xE754, // + 0x8E94,0xE756, // + 0x8E99,0xE757, // + 0x8EA1,0xE759, // + 0x8EAA,0xE758, // + 0x8EAB,0x9067, // + 0x8EAC,0xE75A, // + 0x8EAF,0x8BEB, // + 0x8EB1,0xE75D, // + 0x8EBE,0xE75E, // + 0x8EC5,0xE75F, // + 0x8EC6,0xE75C, // + 0x8EC8,0xE760, // + 0x8ECA,0x8ED4, // + 0x8ECB,0xE761, // + 0x8ECC,0x8B4F, // + 0x8ECD,0x8C52, // + 0x8ED2,0x8CAC, // + 0x8EDB,0xE762, // + 0x8EDF,0x93EE, // + 0x8EE2,0x935D, // + 0x8EE3,0xE763, // + 0x8EEB,0xE766, // + 0x8EF8,0x8EB2, // + 0x8EFB,0xE765, // + 0x8EFC,0xE764, // + 0x8EFD,0x8C79, // + 0x8EFE,0xE767, // + 0x8F03,0x8A72, // + 0x8F05,0xE769, // + 0x8F09,0x8DDA, // + 0x8F0A,0xE768, // + 0x8F0C,0xE771, // + 0x8F12,0xE76B, // + 0x8F13,0xE76D, // + 0x8F14,0x95E3, // + 0x8F15,0xE76A, // + 0x8F19,0xE76C, // + 0x8F1B,0xE770, // + 0x8F1C,0xE76E, // + 0x8F1D,0x8B50, // + 0x8F1F,0xE76F, // + 0x8F26,0xE772, // + 0x8F29,0x9479, // + 0x8F2A,0x97D6, // + 0x8F2F,0x8F53, // + 0x8F33,0xE773, // + 0x8F38,0x9741, // + 0x8F39,0xE775, // + 0x8F3B,0xE774, // + 0x8F3E,0xE778, // + 0x8F3F,0x9760, // + 0x8F42,0xE777, // + 0x8F44,0x8A8D, // + 0x8F45,0xE776, // + 0x8F46,0xE77B, // + 0x8F49,0xE77A, // + 0x8F4C,0xE779, // + 0x8F4D,0x9351, // + 0x8F4E,0xE77C, // + 0x8F57,0xE77D, // + 0x8F5C,0xE77E, // + 0x8F5F,0x8D8C, // + 0x8F61,0x8C44, // + 0x8F62,0xE780, // + 0x8F63,0xE781, // + 0x8F64,0xE782, // + 0x8F9B,0x9068, // + 0x8F9C,0xE783, // + 0x8F9E,0x8EAB, // + 0x8F9F,0xE784, // + 0x8FA3,0xE785, // + 0x8FA7,0x999F, // + 0x8FA8,0x999E, // + 0x8FAD,0xE786, // + 0x8FAE,0xE390, // + 0x8FAF,0xE787, // + 0x8FB0,0x9243, // + 0x8FB1,0x904A, // + 0x8FB2,0x945F, // + 0x8FB7,0xE788, // + 0x8FBA,0x95D3, // + 0x8FBB,0x92D2, // + 0x8FBC,0x8D9E, // + 0x8FBF,0x9248, // + 0x8FC2,0x8949, // + 0x8FC4,0x9698, // + 0x8FC5,0x9076, // + 0x8FCE,0x8C7D, // + 0x8FD1,0x8BDF, // + 0x8FD4,0x95D4, // + 0x8FDA,0xE789, // + 0x8FE2,0xE78B, // + 0x8FE5,0xE78A, // + 0x8FE6,0x89DE, // + 0x8FE9,0x93F4, // + 0x8FEA,0xE78C, // + 0x8FEB,0x9497, // + 0x8FED,0x9352, // + 0x8FEF,0xE78D, // + 0x8FF0,0x8F71, // + 0x8FF4,0xE78F, // + 0x8FF7,0x96C0, // + 0x8FF8,0xE79E, // + 0x8FF9,0xE791, // + 0x8FFA,0xE792, // + 0x8FFD,0x92C7, // + 0x9000,0x91DE, // + 0x9001,0x9197, // + 0x9003,0x93A6, // + 0x9005,0xE790, // + 0x9006,0x8B74, // + 0x900B,0xE799, // + 0x900D,0xE796, // + 0x900E,0xE7A3, // + 0x900F,0x93A7, // + 0x9010,0x9280, // + 0x9011,0xE793, // + 0x9013,0x92FC, // + 0x9014,0x9372, // + 0x9015,0xE794, // + 0x9016,0xE798, // + 0x9017,0x9080, // + 0x9019,0x9487, // + 0x901A,0x92CA, // + 0x901D,0x90C0, // + 0x901E,0xE797, // + 0x901F,0x91AC, // + 0x9020,0x91A2, // + 0x9021,0xE795, // + 0x9022,0x88A7, // + 0x9023,0x9841, // + 0x9027,0xE79A, // + 0x902E,0x91DF, // + 0x9031,0x8F54, // + 0x9032,0x9069, // + 0x9035,0xE79C, // + 0x9036,0xE79B, // + 0x9038,0x88ED, // + 0x9039,0xE79D, // + 0x903C,0x954E, // + 0x903E,0xE7A5, // + 0x9041,0x93D9, // + 0x9042,0x908B, // + 0x9045,0x9278, // + 0x9047,0x8BF6, // + 0x9049,0xE7A4, // + 0x904A,0x9756, // + 0x904B,0x895E, // + 0x904D,0x95D5, // + 0x904E,0x89DF, // + 0x904F,0xE79F, // + 0x9050,0xE7A0, // + 0x9051,0xE7A1, // + 0x9052,0xE7A2, // + 0x9053,0x93B9, // + 0x9054,0x9242, // + 0x9055,0x88E1, // + 0x9056,0xE7A6, // + 0x9058,0xE7A7, // + 0x9059,0xEAA1, // + 0x905C,0x91BB, // + 0x905E,0xE7A8, // + 0x9060,0x8993, // + 0x9061,0x916B, // + 0x9063,0x8CAD, // + 0x9065,0x9779, // + 0x9068,0xE7A9, // + 0x9069,0x934B, // + 0x906D,0x9198, // + 0x906E,0x8ED5, // + 0x906F,0xE7AA, // + 0x9072,0xE7AD, // + 0x9075,0x8F85, // + 0x9076,0xE7AB, // + 0x9077,0x914A, // + 0x9078,0x9149, // + 0x907A,0x88E2, // + 0x907C,0x97C9, // + 0x907D,0xE7AF, // + 0x907F,0x94F0, // + 0x9080,0xE7B1, // + 0x9081,0xE7B0, // + 0x9082,0xE7AE, // + 0x9083,0xE284, // + 0x9084,0x8AD2, // + 0x9087,0xE78E, // + 0x9089,0xE7B3, // + 0x908A,0xE7B2, // + 0x908F,0xE7B4, // + 0x9091,0x9757, // + 0x90A3,0x93DF, // + 0x90A6,0x964D, // + 0x90A8,0xE7B5, // + 0x90AA,0x8ED7, // + 0x90AF,0xE7B6, // + 0x90B1,0xE7B7, // + 0x90B5,0xE7B8, // + 0x90B8,0x9340, // + 0x90C1,0x88E8, // + 0x90CA,0x8D78, // + 0x90CE,0x9859, // + 0x90DB,0xE7BC, // + 0x90E1,0x8C53, // + 0x90E2,0xE7B9, // + 0x90E4,0xE7BA, // + 0x90E8,0x9594, // + 0x90ED,0x8A73, // + 0x90F5,0x9758, // + 0x90F7,0x8BBD, // + 0x90FD,0x9373, // + 0x9102,0xE7BD, // + 0x9112,0xE7BE, // + 0x9119,0xE7BF, // + 0x912D,0x9341, // + 0x9130,0xE7C1, // + 0x9132,0xE7C0, // + 0x9149,0x93D1, // + 0x914A,0xE7C2, // + 0x914B,0x8F55, // + 0x914C,0x8EDE, // + 0x914D,0x947A, // + 0x914E,0x9291, // + 0x9152,0x8EF0, // + 0x9154,0x908C, // + 0x9156,0xE7C3, // + 0x9158,0xE7C4, // + 0x9162,0x907C, // + 0x9163,0xE7C5, // + 0x9165,0xE7C6, // + 0x9169,0xE7C7, // + 0x916A,0x978F, // + 0x916C,0x8F56, // + 0x9172,0xE7C9, // + 0x9173,0xE7C8, // + 0x9175,0x8D79, // + 0x9177,0x8D93, // + 0x9178,0x8E5F, // + 0x9182,0xE7CC, // + 0x9187,0x8F86, // + 0x9189,0xE7CB, // + 0x918B,0xE7CA, // + 0x918D,0x91E7, // + 0x9190,0x8CED, // + 0x9192,0x90C1, // + 0x9197,0x94AE, // + 0x919C,0x8F58, // + 0x91A2,0xE7CD, // + 0x91A4,0x8FDD, // + 0x91AA,0xE7D0, // + 0x91AB,0xE7CE, // + 0x91AF,0xE7CF, // + 0x91B4,0xE7D2, // + 0x91B5,0xE7D1, // + 0x91B8,0x8FF8, // + 0x91BA,0xE7D3, // + 0x91C0,0xE7D4, // + 0x91C1,0xE7D5, // + 0x91C6,0x94CE, // + 0x91C7,0x8DD1, // + 0x91C8,0x8EDF, // + 0x91C9,0xE7D6, // + 0x91CB,0xE7D7, // + 0x91CC,0x97A2, // + 0x91CD,0x8F64, // + 0x91CE,0x96EC, // + 0x91CF,0x97CA, // + 0x91D0,0xE7D8, // + 0x91D1,0x8BE0, // + 0x91D6,0xE7D9, // + 0x91D8,0x9342, // + 0x91DB,0xE7DC, // + 0x91DC,0x8A98, // + 0x91DD,0x906A, // + 0x91DF,0xE7DA, // + 0x91E1,0xE7DB, // + 0x91E3,0x92DE, // + 0x91E6,0x9674, // + 0x91E7,0x8BFA, // + 0x91F5,0xE7DE, // + 0x91F6,0xE7DF, // + 0x91FC,0xE7DD, // + 0x91FF,0xE7E1, // + 0x920D,0x93DD, // + 0x920E,0x8A62, // + 0x9211,0xE7E5, // + 0x9214,0xE7E2, // + 0x9215,0xE7E4, // + 0x921E,0xE7E0, // + 0x9229,0xE86E, // + 0x922C,0xE7E3, // + 0x9234,0x97E9, // + 0x9237,0x8CD8, // + 0x923F,0xE7ED, // + 0x9244,0x9353, // + 0x9245,0xE7E8, // + 0x9248,0xE7EB, // + 0x9249,0xE7E9, // + 0x924B,0xE7EE, // + 0x9250,0xE7EF, // + 0x9257,0xE7E7, // + 0x925A,0xE7F4, // + 0x925B,0x8994, // + 0x925E,0xE7E6, // + 0x9262,0x94AB, // + 0x9264,0xE7EA, // + 0x9266,0x8FDE, // + 0x9271,0x8D7A, // + 0x927E,0x9667, // + 0x9280,0x8BE2, // + 0x9283,0x8F65, // + 0x9285,0x93BA, // + 0x9291,0x914C, // + 0x9293,0xE7F2, // + 0x9295,0xE7EC, // + 0x9296,0xE7F1, // + 0x9298,0x96C1, // + 0x929A,0x92B6, // + 0x929B,0xE7F3, // + 0x929C,0xE7F0, // + 0x92AD,0x914B, // + 0x92B7,0xE7F7, // + 0x92B9,0xE7F6, // + 0x92CF,0xE7F5, // + 0x92D2,0x964E, // + 0x92E4,0x8F9B, // + 0x92E9,0xE7F8, // + 0x92EA,0x95DD, // + 0x92ED,0x8973, // + 0x92F2,0x9565, // + 0x92F3,0x9292, // + 0x92F8,0x8B98, // + 0x92FA,0xE7FA, // + 0x92FC,0x8D7C, // + 0x9306,0x8E4B, // + 0x930F,0xE7F9, // + 0x9310,0x908D, // + 0x9318,0x908E, // + 0x9319,0xE840, // + 0x931A,0xE842, // + 0x9320,0x8FF9, // + 0x9322,0xE841, // + 0x9323,0xE843, // + 0x9326,0x8BD1, // + 0x9328,0x9564, // + 0x932B,0x8EE0, // + 0x932C,0x9842, // + 0x932E,0xE7FC, // + 0x932F,0x8DF6, // + 0x9332,0x985E, // + 0x9335,0xE845, // + 0x933A,0xE844, // + 0x933B,0xE846, // + 0x9344,0xE7FB, // + 0x934B,0x93E7, // + 0x934D,0x9374, // + 0x9354,0x92D5, // + 0x9356,0xE84B, // + 0x935B,0x9262, // + 0x935C,0xE847, // + 0x9360,0xE848, // + 0x936C,0x8C4C, // + 0x936E,0xE84A, // + 0x9375,0x8CAE, // + 0x937C,0xE849, // + 0x937E,0x8FDF, // + 0x938C,0x8A99, // + 0x9394,0xE84F, // + 0x9396,0x8DBD, // + 0x9397,0x9199, // + 0x939A,0x92C8, // + 0x93A7,0x8A5A, // + 0x93AC,0xE84D, // + 0x93AD,0xE84E, // + 0x93AE,0x92C1, // + 0x93B0,0xE84C, // + 0x93B9,0xE850, // + 0x93C3,0xE856, // + 0x93C8,0xE859, // + 0x93D0,0xE858, // + 0x93D1,0x934C, // + 0x93D6,0xE851, // + 0x93D7,0xE852, // + 0x93D8,0xE855, // + 0x93DD,0xE857, // + 0x93E1,0x8BBE, // + 0x93E4,0xE85A, // + 0x93E5,0xE854, // + 0x93E8,0xE853, // + 0x9403,0xE85E, // + 0x9407,0xE85F, // + 0x9410,0xE860, // + 0x9413,0xE85D, // + 0x9414,0xE85C, // + 0x9418,0x8FE0, // + 0x9419,0x93A8, // + 0x9421,0xE864, // + 0x942B,0xE862, // + 0x9435,0xE863, // + 0x9436,0xE861, // + 0x9438,0x91F6, // + 0x943A,0xE865, // + 0x9441,0xE866, // + 0x9444,0xE868, // + 0x9451,0x8AD3, // + 0x9452,0xE867, // + 0x9453,0x96F8, // + 0x945A,0xE873, // + 0x945B,0xE869, // + 0x945E,0xE86C, // + 0x9460,0xE86A, // + 0x9462,0xE86B, // + 0x946A,0xE86D, // + 0x9470,0xE86F, // + 0x9475,0xE870, // + 0x9477,0xE871, // + 0x947C,0xE874, // + 0x947D,0xE872, // + 0x947E,0xE875, // + 0x947F,0xE877, // + 0x9481,0xE876, // + 0x9577,0x92B7, // + 0x9580,0x96E5, // + 0x9582,0xE878, // + 0x9583,0x914D, // + 0x9587,0xE879, // + 0x9589,0x95C2, // + 0x958A,0xE87A, // + 0x958B,0x8A4A, // + 0x9591,0x8AD5, // + 0x9593,0x8AD4, // + 0x9594,0xE87B, // + 0x9596,0xE87C, // + 0x9598,0xE87D, // + 0x9599,0xE87E, // + 0x95A0,0xE880, // + 0x95A2,0x8AD6, // + 0x95A3,0x8A74, // + 0x95A4,0x8D7D, // + 0x95A5,0x94B4, // + 0x95A7,0xE882, // + 0x95A8,0xE881, // + 0x95AD,0xE883, // + 0x95B2,0x897B, // + 0x95B9,0xE886, // + 0x95BB,0xE885, // + 0x95BC,0xE884, // + 0x95BE,0xE887, // + 0x95C3,0xE88A, // + 0x95C7,0x88C5, // + 0x95CA,0xE888, // + 0x95CC,0xE88C, // + 0x95CD,0xE88B, // + 0x95D4,0xE88E, // + 0x95D5,0xE88D, // + 0x95D6,0xE88F, // + 0x95D8,0x93AC, // + 0x95DC,0xE890, // + 0x95E1,0xE891, // + 0x95E2,0xE893, // + 0x95E5,0xE892, // + 0x961C,0x958C, // + 0x9621,0xE894, // + 0x9628,0xE895, // + 0x962A,0x8DE3, // + 0x962E,0xE896, // + 0x962F,0xE897, // + 0x9632,0x9668, // + 0x963B,0x916A, // + 0x963F,0x88A2, // + 0x9640,0x91C9, // + 0x9642,0xE898, // + 0x9644,0x958D, // + 0x964B,0xE89B, // + 0x964C,0xE899, // + 0x964D,0x8D7E, // + 0x964F,0xE89A, // + 0x9650,0x8CC0, // + 0x965B,0x95C3, // + 0x965C,0xE89D, // + 0x965D,0xE89F, // + 0x965E,0xE89E, // + 0x965F,0xE8A0, // + 0x9662,0x8940, // + 0x9663,0x9077, // + 0x9664,0x8F9C, // + 0x9665,0x8AD7, // + 0x9666,0xE8A1, // + 0x966A,0x9486, // + 0x966C,0xE8A3, // + 0x9670,0x8941, // + 0x9672,0xE8A2, // + 0x9673,0x92C2, // + 0x9675,0x97CB, // + 0x9676,0x93A9, // + 0x9677,0xE89C, // + 0x9678,0x97A4, // + 0x967A,0x8CAF, // + 0x967D,0x977A, // + 0x9685,0x8BF7, // + 0x9686,0x97B2, // + 0x9688,0x8C47, // + 0x968A,0x91E0, // + 0x968B,0xE440, // + 0x968D,0xE8A4, // + 0x968E,0x8A4B, // + 0x968F,0x908F, // + 0x9694,0x8A75, // + 0x9695,0xE8A6, // + 0x9697,0xE8A7, // + 0x9698,0xE8A5, // + 0x9699,0x8C84, // + 0x969B,0x8DDB, // + 0x969C,0x8FE1, // + 0x96A0,0x8942, // + 0x96A3,0x97D7, // + 0x96A7,0xE8A9, // + 0x96A8,0xE7AC, // + 0x96AA,0xE8A8, // + 0x96B0,0xE8AC, // + 0x96B1,0xE8AA, // + 0x96B2,0xE8AB, // + 0x96B4,0xE8AD, // + 0x96B6,0xE8AE, // + 0x96B7,0x97EA, // + 0x96B8,0xE8AF, // + 0x96B9,0xE8B0, // + 0x96BB,0x90C7, // + 0x96BC,0x94B9, // + 0x96C0,0x909D, // + 0x96C1,0x8AE5, // + 0x96C4,0x9759, // + 0x96C5,0x89EB, // + 0x96C6,0x8F57, // + 0x96C7,0x8CD9, // + 0x96C9,0xE8B3, // + 0x96CB,0xE8B2, // + 0x96CC,0x8E93, // + 0x96CD,0xE8B4, // + 0x96CE,0xE8B1, // + 0x96D1,0x8E47, // + 0x96D5,0xE8B8, // + 0x96D6,0xE5AB, // + 0x96D9,0x99D4, // + 0x96DB,0x9097, // + 0x96DC,0xE8B6, // + 0x96E2,0x97A3, // + 0x96E3,0x93EF, // + 0x96E8,0x894A, // + 0x96EA,0x90E1, // + 0x96EB,0x8EB4, // + 0x96F0,0x95B5, // + 0x96F2,0x895F, // + 0x96F6,0x97EB, // + 0x96F7,0x978B, // + 0x96F9,0xE8B9, // + 0x96FB,0x9364, // + 0x9700,0x8EF9, // + 0x9704,0xE8BA, // + 0x9706,0xE8BB, // + 0x9707,0x906B, // + 0x9708,0xE8BC, // + 0x970A,0x97EC, // + 0x970D,0xE8B7, // + 0x970E,0xE8BE, // + 0x970F,0xE8C0, // + 0x9711,0xE8BF, // + 0x9713,0xE8BD, // + 0x9716,0xE8C1, // + 0x9719,0xE8C2, // + 0x971C,0x919A, // + 0x971E,0x89E0, // + 0x9724,0xE8C3, // + 0x9727,0x96B6, // + 0x972A,0xE8C4, // + 0x9730,0xE8C5, // + 0x9732,0x9849, // + 0x9738,0x9E50, // + 0x9739,0xE8C6, // + 0x973D,0xE8C7, // + 0x973E,0xE8C8, // + 0x9742,0xE8CC, // + 0x9744,0xE8C9, // + 0x9746,0xE8CA, // + 0x9748,0xE8CB, // + 0x9749,0xE8CD, // + 0x9752,0x90C2, // + 0x9756,0x96F5, // + 0x9759,0x90C3, // + 0x975C,0xE8CE, // + 0x975E,0x94F1, // + 0x9760,0xE8CF, // + 0x9761,0xEA72, // + 0x9762,0x96CA, // + 0x9764,0xE8D0, // + 0x9766,0xE8D1, // + 0x9768,0xE8D2, // + 0x9769,0x8A76, // + 0x976B,0xE8D4, // + 0x976D,0x9078, // + 0x9771,0xE8D5, // + 0x9774,0x8C43, // + 0x9779,0xE8D6, // + 0x977A,0xE8DA, // + 0x977C,0xE8D8, // + 0x9781,0xE8D9, // + 0x9784,0x8A93, // + 0x9785,0xE8D7, // + 0x9786,0xE8DB, // + 0x978B,0xE8DC, // + 0x978D,0x88C6, // + 0x978F,0xE8DD, // + 0x9790,0xE8DE, // + 0x9798,0x8FE2, // + 0x979C,0xE8DF, // + 0x97A0,0x8B66, // + 0x97A3,0xE8E2, // + 0x97A6,0xE8E1, // + 0x97A8,0xE8E0, // + 0x97AB,0xE691, // + 0x97AD,0x95DA, // + 0x97B3,0xE8E3, // + 0x97B4,0xE8E4, // + 0x97C3,0xE8E5, // + 0x97C6,0xE8E6, // + 0x97C8,0xE8E7, // + 0x97CB,0xE8E8, // + 0x97D3,0x8AD8, // + 0x97DC,0xE8E9, // + 0x97ED,0xE8EA, // + 0x97EE,0x9442, // + 0x97F2,0xE8EC, // + 0x97F3,0x89B9, // + 0x97F5,0xE8EF, // + 0x97F6,0xE8EE, // + 0x97FB,0x8943, // + 0x97FF,0x8BBF, // + 0x9801,0x95C5, // + 0x9802,0x92B8, // + 0x9803,0x8DA0, // + 0x9805,0x8D80, // + 0x9806,0x8F87, // + 0x9808,0x907B, // + 0x980C,0xE8F1, // + 0x980F,0xE8F0, // + 0x9810,0x9761, // + 0x9811,0x8AE6, // + 0x9812,0x94D0, // + 0x9813,0x93DA, // + 0x9817,0x909C, // + 0x9818,0x97CC, // + 0x981A,0x8C7A, // + 0x9821,0xE8F4, // + 0x9824,0xE8F3, // + 0x982C,0x966A, // + 0x982D,0x93AA, // + 0x9834,0x896F, // + 0x9837,0xE8F5, // + 0x9838,0xE8F2, // + 0x983B,0x9570, // + 0x983C,0x978A, // + 0x983D,0xE8F6, // + 0x9846,0xE8F7, // + 0x984B,0xE8F9, // + 0x984C,0x91E8, // + 0x984D,0x8A7A, // + 0x984E,0x8A7B, // + 0x984F,0xE8F8, // + 0x9854,0x8AE7, // + 0x9855,0x8CB0, // + 0x9858,0x8AE8, // + 0x985B,0x935E, // + 0x985E,0x97DE, // + 0x9867,0x8CDA, // + 0x986B,0xE8FA, // + 0x986F,0xE8FB, // + 0x9870,0xE8FC, // + 0x9871,0xE940, // + 0x9873,0xE942, // + 0x9874,0xE941, // + 0x98A8,0x9597, // + 0x98AA,0xE943, // + 0x98AF,0xE944, // + 0x98B1,0xE945, // + 0x98B6,0xE946, // + 0x98C3,0xE948, // + 0x98C4,0xE947, // + 0x98C6,0xE949, // + 0x98DB,0x94F2, // + 0x98DC,0xE3CA, // + 0x98DF,0x9048, // + 0x98E2,0x8B51, // + 0x98E9,0xE94A, // + 0x98EB,0xE94B, // + 0x98ED,0x99AA, // + 0x98EE,0x9F5A, // + 0x98EF,0x94D1, // + 0x98F2,0x88F9, // + 0x98F4,0x88B9, // + 0x98FC,0x8E94, // + 0x98FD,0x964F, // + 0x98FE,0x8FFC, // + 0x9903,0xE94C, // + 0x9905,0x96DD, // + 0x9909,0xE94D, // + 0x990A,0x977B, // + 0x990C,0x8961, // + 0x9910,0x8E60, // + 0x9912,0xE94E, // + 0x9913,0x89EC, // + 0x9914,0xE94F, // + 0x9918,0xE950, // + 0x991D,0xE952, // + 0x991E,0xE953, // + 0x9920,0xE955, // + 0x9921,0xE951, // + 0x9924,0xE954, // + 0x9928,0x8AD9, // + 0x992C,0xE956, // + 0x992E,0xE957, // + 0x993D,0xE958, // + 0x993E,0xE959, // + 0x9942,0xE95A, // + 0x9945,0xE95C, // + 0x994B,0xE95E, // + 0x994C,0xE961, // + 0x9950,0xE95D, // + 0x9951,0xE95F, // + 0x9952,0xE960, // + 0x9955,0xE962, // + 0x9957,0x8BC0, // + 0x9996,0x8EF1, // + 0x9997,0xE963, // + 0x9998,0xE964, // + 0x9999,0x8D81, // + 0x99A5,0xE965, // + 0x99A8,0x8A5D, // + 0x99AC,0x946E, // + 0x99AD,0xE966, // + 0x99AE,0xE967, // + 0x99B3,0x9279, // + 0x99B4,0x93E9, // + 0x99BC,0xE968, // + 0x99C1,0x949D, // + 0x99C4,0x91CA, // + 0x99C5,0x8977, // + 0x99C6,0x8BEC, // + 0x99C8,0x8BED, // + 0x99D0,0x9293, // + 0x99D1,0xE96D, // + 0x99D2,0x8BEE, // + 0x99D5,0x89ED, // + 0x99D8,0xE96C, // + 0x99DB,0xE96A, // + 0x99DD,0xE96B, // + 0x99DF,0xE969, // + 0x99E2,0xE977, // + 0x99ED,0xE96E, // + 0x99EE,0xE96F, // + 0x99F1,0xE970, // + 0x99F2,0xE971, // + 0x99F8,0xE973, // + 0x99FB,0xE972, // + 0x99FF,0x8F78, // + 0x9A01,0xE974, // + 0x9A05,0xE976, // + 0x9A0E,0x8B52, // + 0x9A0F,0xE975, // + 0x9A12,0x919B, // + 0x9A13,0x8CB1, // + 0x9A19,0xE978, // + 0x9A28,0x91CB, // + 0x9A2B,0xE979, // + 0x9A30,0x93AB, // + 0x9A37,0xE97A, // + 0x9A3E,0xE980, // + 0x9A40,0xE97D, // + 0x9A42,0xE97C, // + 0x9A43,0xE97E, // + 0x9A45,0xE97B, // + 0x9A4D,0xE982, // + 0x9A55,0xE981, // + 0x9A57,0xE984, // + 0x9A5A,0x8BC1, // + 0x9A5B,0xE983, // + 0x9A5F,0xE985, // + 0x9A62,0xE986, // + 0x9A64,0xE988, // + 0x9A65,0xE987, // + 0x9A69,0xE989, // + 0x9A6A,0xE98B, // + 0x9A6B,0xE98A, // + 0x9AA8,0x8D9C, // + 0x9AAD,0xE98C, // + 0x9AB0,0xE98D, // + 0x9ABC,0xE98E, // + 0x9AC0,0xE98F, // + 0x9AC4,0x9091, // + 0x9ACF,0xE990, // + 0x9AD1,0xE991, // + 0x9AD3,0xE992, // + 0x9AD4,0xE993, // + 0x9AD8,0x8D82, // + 0x9ADE,0xE994, // + 0x9ADF,0xE995, // + 0x9AE2,0xE996, // + 0x9AE3,0xE997, // + 0x9AE6,0xE998, // + 0x9AEA,0x94AF, // + 0x9AEB,0xE99A, // + 0x9AED,0x9545, // + 0x9AEE,0xE99B, // + 0x9AEF,0xE999, // + 0x9AF1,0xE99D, // + 0x9AF4,0xE99C, // + 0x9AF7,0xE99E, // + 0x9AFB,0xE99F, // + 0x9B06,0xE9A0, // + 0x9B18,0xE9A1, // + 0x9B1A,0xE9A2, // + 0x9B1F,0xE9A3, // + 0x9B22,0xE9A4, // + 0x9B23,0xE9A5, // + 0x9B25,0xE9A6, // + 0x9B27,0xE9A7, // + 0x9B28,0xE9A8, // + 0x9B29,0xE9A9, // + 0x9B2A,0xE9AA, // + 0x9B2E,0xE9AB, // + 0x9B2F,0xE9AC, // + 0x9B31,0x9F54, // + 0x9B32,0xE9AD, // + 0x9B3B,0xE2F6, // + 0x9B3C,0x8B53, // + 0x9B41,0x8A40, // + 0x9B42,0x8DB0, // + 0x9B43,0xE9AF, // + 0x9B44,0xE9AE, // + 0x9B45,0x96A3, // + 0x9B4D,0xE9B1, // + 0x9B4E,0xE9B2, // + 0x9B4F,0xE9B0, // + 0x9B51,0xE9B3, // + 0x9B54,0x9682, // + 0x9B58,0xE9B4, // + 0x9B5A,0x8B9B, // + 0x9B6F,0x9844, // + 0x9B74,0xE9B5, // + 0x9B83,0xE9B7, // + 0x9B8E,0x88BC, // + 0x9B91,0xE9B8, // + 0x9B92,0x95A9, // + 0x9B93,0xE9B6, // + 0x9B96,0xE9B9, // + 0x9B97,0xE9BA, // + 0x9B9F,0xE9BB, // + 0x9BA0,0xE9BC, // + 0x9BA8,0xE9BD, // + 0x9BAA,0x968E, // + 0x9BAB,0x8E4C, // + 0x9BAD,0x8DF8, // + 0x9BAE,0x914E, // + 0x9BB4,0xE9BE, // + 0x9BB9,0xE9C1, // + 0x9BC0,0xE9BF, // + 0x9BC6,0xE9C2, // + 0x9BC9,0x8CEF, // + 0x9BCA,0xE9C0, // + 0x9BCF,0xE9C3, // + 0x9BD1,0xE9C4, // + 0x9BD2,0xE9C5, // + 0x9BD4,0xE9C9, // + 0x9BD6,0x8E49, // + 0x9BDB,0x91E2, // + 0x9BE1,0xE9CA, // + 0x9BE2,0xE9C7, // + 0x9BE3,0xE9C6, // + 0x9BE4,0xE9C8, // + 0x9BE8,0x8C7E, // + 0x9BF0,0xE9CE, // + 0x9BF1,0xE9CD, // + 0x9BF2,0xE9CC, // + 0x9BF5,0x88B1, // + 0x9C04,0xE9D8, // + 0x9C06,0xE9D4, // + 0x9C08,0xE9D5, // + 0x9C09,0xE9D1, // + 0x9C0A,0xE9D7, // + 0x9C0C,0xE9D3, // + 0x9C0D,0x8A82, // + 0x9C10,0x986B, // + 0x9C12,0xE9D6, // + 0x9C13,0xE9D2, // + 0x9C14,0xE9D0, // + 0x9C15,0xE9CF, // + 0x9C1B,0xE9DA, // + 0x9C21,0xE9DD, // + 0x9C24,0xE9DC, // + 0x9C25,0xE9DB, // + 0x9C2D,0x9568, // + 0x9C2E,0xE9D9, // + 0x9C2F,0x88F1, // + 0x9C30,0xE9DE, // + 0x9C32,0xE9E0, // + 0x9C39,0x8A8F, // + 0x9C3A,0xE9CB, // + 0x9C3B,0x8956, // + 0x9C3E,0xE9E2, // + 0x9C46,0xE9E1, // + 0x9C47,0xE9DF, // + 0x9C48,0x924C, // + 0x9C52,0x9690, // + 0x9C57,0x97D8, // + 0x9C5A,0xE9E3, // + 0x9C60,0xE9E4, // + 0x9C67,0xE9E5, // + 0x9C76,0xE9E6, // + 0x9C78,0xE9E7, // + 0x9CE5,0x92B9, // + 0x9CE7,0xE9E8, // + 0x9CE9,0x94B5, // + 0x9CEB,0xE9ED, // + 0x9CEC,0xE9E9, // + 0x9CF0,0xE9EA, // + 0x9CF3,0x9650, // + 0x9CF4,0x96C2, // + 0x9CF6,0x93CE, // + 0x9D03,0xE9EE, // + 0x9D06,0xE9EF, // + 0x9D07,0x93BC, // + 0x9D08,0xE9EC, // + 0x9D09,0xE9EB, // + 0x9D0E,0x89A8, // + 0x9D12,0xE9F7, // + 0x9D15,0xE9F6, // + 0x9D1B,0x8995, // + 0x9D1F,0xE9F4, // + 0x9D23,0xE9F3, // + 0x9D26,0xE9F1, // + 0x9D28,0x8A9B, // + 0x9D2A,0xE9F0, // + 0x9D2B,0x8EB0, // + 0x9D2C,0x89A7, // + 0x9D3B,0x8D83, // + 0x9D3E,0xE9FA, // + 0x9D3F,0xE9F9, // + 0x9D41,0xE9F8, // + 0x9D44,0xE9F5, // + 0x9D46,0xE9FB, // + 0x9D48,0xE9FC, // + 0x9D50,0xEA44, // + 0x9D51,0xEA43, // + 0x9D59,0xEA45, // + 0x9D5C,0x894C, // + 0x9D5D,0xEA40, // + 0x9D5E,0xEA41, // + 0x9D60,0x8D94, // + 0x9D61,0x96B7, // + 0x9D64,0xEA42, // + 0x9D6C,0x9651, // + 0x9D6F,0xEA4A, // + 0x9D72,0xEA46, // + 0x9D7A,0xEA4B, // + 0x9D87,0xEA48, // + 0x9D89,0xEA47, // + 0x9D8F,0x8C7B, // + 0x9D9A,0xEA4C, // + 0x9DA4,0xEA4D, // + 0x9DA9,0xEA4E, // + 0x9DAB,0xEA49, // + 0x9DAF,0xE9F2, // + 0x9DB2,0xEA4F, // + 0x9DB4,0x92DF, // + 0x9DB8,0xEA53, // + 0x9DBA,0xEA54, // + 0x9DBB,0xEA52, // + 0x9DC1,0xEA51, // + 0x9DC2,0xEA57, // + 0x9DC4,0xEA50, // + 0x9DC6,0xEA55, // + 0x9DCF,0xEA56, // + 0x9DD3,0xEA59, // + 0x9DD9,0xEA58, // + 0x9DED,0xEA5C, // + 0x9DEF,0xEA5D, // + 0x9DF2,0x9868, // + 0x9DF8,0xEA5A, // + 0x9DF9,0x91E9, // + 0x9DFA,0x8DEB, // + 0x9DFD,0xEA5E, // + 0x9E1A,0xEA5F, // + 0x9E1B,0xEA60, // + 0x9E1E,0xEA61, // + 0x9E75,0xEA62, // + 0x9E78,0x8CB2, // + 0x9E79,0xEA63, // + 0x9E7D,0xEA64, // + 0x9E7F,0x8EAD, // + 0x9E81,0xEA65, // + 0x9E88,0xEA66, // + 0x9E8B,0xEA67, // + 0x9E8C,0xEA68, // + 0x9E91,0xEA6B, // + 0x9E92,0xEA69, // + 0x9E95,0xEA6A, // + 0x9E97,0x97ED, // + 0x9E9D,0xEA6C, // + 0x9E9F,0x97D9, // + 0x9EA5,0xEA6D, // + 0x9EA6,0x949E, // + 0x9EA9,0xEA6E, // + 0x9EAA,0xEA70, // + 0x9EAD,0xEA71, // + 0x9EB8,0xEA6F, // + 0x9EB9,0x8D8D, // + 0x9EBA,0x96CB, // + 0x9EBB,0x9683, // + 0x9EBC,0x9BF5, // + 0x9EBE,0x9F80, // + 0x9EBF,0x969B, // + 0x9EC4,0x89A9, // + 0x9ECC,0xEA73, // + 0x9ECD,0x8B6F, // + 0x9ECE,0xEA74, // + 0x9ECF,0xEA75, // + 0x9ED0,0xEA76, // + 0x9ED2,0x8D95, // + 0x9ED4,0xEA77, // + 0x9ED8,0xE0D2, // + 0x9ED9,0x96D9, // + 0x9EDB,0x91E1, // + 0x9EDC,0xEA78, // + 0x9EDD,0xEA7A, // + 0x9EDE,0xEA79, // + 0x9EE0,0xEA7B, // + 0x9EE5,0xEA7C, // + 0x9EE8,0xEA7D, // + 0x9EEF,0xEA7E, // + 0x9EF4,0xEA80, // + 0x9EF6,0xEA81, // + 0x9EF7,0xEA82, // + 0x9EF9,0xEA83, // + 0x9EFB,0xEA84, // + 0x9EFC,0xEA85, // + 0x9EFD,0xEA86, // + 0x9F07,0xEA87, // + 0x9F08,0xEA88, // + 0x9F0E,0x9343, // + 0x9F13,0x8CDB, // + 0x9F15,0xEA8A, // + 0x9F20,0x916C, // + 0x9F21,0xEA8B, // + 0x9F2C,0xEA8C, // + 0x9F3B,0x9540, // + 0x9F3E,0xEA8D, // + 0x9F4A,0xEA8E, // + 0x9F4B,0xE256, // + 0x9F4E,0xE6D8, // + 0x9F4F,0xE8EB, // + 0x9F52,0xEA8F, // + 0x9F54,0xEA90, // + 0x9F5F,0xEA92, // + 0x9F60,0xEA93, // + 0x9F61,0xEA94, // + 0x9F62,0x97EE, // + 0x9F63,0xEA91, // + 0x9F66,0xEA95, // + 0x9F67,0xEA96, // + 0x9F6A,0xEA98, // + 0x9F6C,0xEA97, // + 0x9F72,0xEA9A, // + 0x9F76,0xEA9B, // + 0x9F77,0xEA99, // + 0x9F8D,0x97B4, // + 0x9F95,0xEA9C, // + 0x9F9C,0xEA9D, // + 0x9F9D,0xE273, // + 0x9FA0,0xEA9E, // + 0xFF01,0x8149, // FULLWIDTH EXCLAMATION MARK + 0xFF03,0x8194, // FULLWIDTH NUMBER SIGN + 0xFF04,0x8190, // FULLWIDTH DOLLAR SIGN + 0xFF05,0x8193, // FULLWIDTH PERCENT SIGN + 0xFF06,0x8195, // FULLWIDTH AMPERSAND + 0xFF07,0x81AD, // FULLWIDTH APOSTROPHE + 0xFF08,0x8169, // FULLWIDTH LEFT PARENTHESIS + 0xFF09,0x816A, // FULLWIDTH RIGHT PARENTHESIS + 0xFF0A,0x8196, // FULLWIDTH ASTERISK + 0xFF0B,0x817B, // FULLWIDTH PLUS SIGN + 0xFF0C,0x8143, // FULLWIDTH COMMA + 0xFF0E,0x8144, // FULLWIDTH FULL STOP + 0xFF0F,0x815E, // FULLWIDTH SOLIDUS + 0xFF10,0x824F, // FULLWIDTH DIGIT ZERO + 0xFF11,0x8250, // FULLWIDTH DIGIT ONE + 0xFF12,0x8251, // FULLWIDTH DIGIT TWO + 0xFF13,0x8252, // FULLWIDTH DIGIT THREE + 0xFF14,0x8253, // FULLWIDTH DIGIT FOUR + 0xFF15,0x8254, // FULLWIDTH DIGIT FIVE + 0xFF16,0x8255, // FULLWIDTH DIGIT SIX + 0xFF17,0x8256, // FULLWIDTH DIGIT SEVEN + 0xFF18,0x8257, // FULLWIDTH DIGIT EIGHT + 0xFF19,0x8258, // FULLWIDTH DIGIT NINE + 0xFF1A,0x8146, // FULLWIDTH COLON + 0xFF1B,0x8147, // FULLWIDTH SEMICOLON + 0xFF1C,0x8183, // FULLWIDTH LESS-THAN SIGN + 0xFF1D,0x8181, // FULLWIDTH EQUALS SIGN + 0xFF1E,0x8184, // FULLWIDTH GREATER-THAN SIGN + 0xFF1F,0x8148, // FULLWIDTH QUESTION MARK + 0xFF20,0x8197, // FULLWIDTH COMMERCIAL AT + 0xFF21,0x8260, // FULLWIDTH LATIN CAPITAL LETTER A + 0xFF22,0x8261, // FULLWIDTH LATIN CAPITAL LETTER B + 0xFF23,0x8262, // FULLWIDTH LATIN CAPITAL LETTER C + 0xFF24,0x8263, // FULLWIDTH LATIN CAPITAL LETTER D + 0xFF25,0x8264, // FULLWIDTH LATIN CAPITAL LETTER E + 0xFF26,0x8265, // FULLWIDTH LATIN CAPITAL LETTER F + 0xFF27,0x8266, // FULLWIDTH LATIN CAPITAL LETTER G + 0xFF28,0x8267, // FULLWIDTH LATIN CAPITAL LETTER H + 0xFF29,0x8268, // FULLWIDTH LATIN CAPITAL LETTER I + 0xFF2A,0x8269, // FULLWIDTH LATIN CAPITAL LETTER J + 0xFF2B,0x826A, // FULLWIDTH LATIN CAPITAL LETTER K + 0xFF2C,0x826B, // FULLWIDTH LATIN CAPITAL LETTER L + 0xFF2D,0x826C, // FULLWIDTH LATIN CAPITAL LETTER M + 0xFF2E,0x826D, // FULLWIDTH LATIN CAPITAL LETTER N + 0xFF2F,0x826E, // FULLWIDTH LATIN CAPITAL LETTER O + 0xFF30,0x826F, // FULLWIDTH LATIN CAPITAL LETTER P + 0xFF31,0x8270, // FULLWIDTH LATIN CAPITAL LETTER Q + 0xFF32,0x8271, // FULLWIDTH LATIN CAPITAL LETTER R + 0xFF33,0x8272, // FULLWIDTH LATIN CAPITAL LETTER S + 0xFF34,0x8273, // FULLWIDTH LATIN CAPITAL LETTER T + 0xFF35,0x8274, // FULLWIDTH LATIN CAPITAL LETTER U + 0xFF36,0x8275, // FULLWIDTH LATIN CAPITAL LETTER V + 0xFF37,0x8276, // FULLWIDTH LATIN CAPITAL LETTER W + 0xFF38,0x8277, // FULLWIDTH LATIN CAPITAL LETTER X + 0xFF39,0x8278, // FULLWIDTH LATIN CAPITAL LETTER Y + 0xFF3A,0x8279, // FULLWIDTH LATIN CAPITAL LETTER Z + 0xFF3B,0x816D, // FULLWIDTH LEFT SQUARE BRACKET + 0xFF3D,0x816E, // FULLWIDTH RIGHT SQUARE BRACKET + 0xFF3E,0x814F, // FULLWIDTH CIRCUMFLEX ACCENT + 0xFF3F,0x8151, // FULLWIDTH LOW LINE + 0xFF40,0x814D, // FULLWIDTH GRAVE ACCENT + 0xFF41,0x8281, // FULLWIDTH LATIN SMALL LETTER A + 0xFF42,0x8282, // FULLWIDTH LATIN SMALL LETTER B + 0xFF43,0x8283, // FULLWIDTH LATIN SMALL LETTER C + 0xFF44,0x8284, // FULLWIDTH LATIN SMALL LETTER D + 0xFF45,0x8285, // FULLWIDTH LATIN SMALL LETTER E + 0xFF46,0x8286, // FULLWIDTH LATIN SMALL LETTER F + 0xFF47,0x8287, // FULLWIDTH LATIN SMALL LETTER G + 0xFF48,0x8288, // FULLWIDTH LATIN SMALL LETTER H + 0xFF49,0x8289, // FULLWIDTH LATIN SMALL LETTER I + 0xFF4A,0x828A, // FULLWIDTH LATIN SMALL LETTER J + 0xFF4B,0x828B, // FULLWIDTH LATIN SMALL LETTER K + 0xFF4C,0x828C, // FULLWIDTH LATIN SMALL LETTER L + 0xFF4D,0x828D, // FULLWIDTH LATIN SMALL LETTER M + 0xFF4E,0x828E, // FULLWIDTH LATIN SMALL LETTER N + 0xFF4F,0x828F, // FULLWIDTH LATIN SMALL LETTER O + 0xFF50,0x8290, // FULLWIDTH LATIN SMALL LETTER P + 0xFF51,0x8291, // FULLWIDTH LATIN SMALL LETTER Q + 0xFF52,0x8292, // FULLWIDTH LATIN SMALL LETTER R + 0xFF53,0x8293, // FULLWIDTH LATIN SMALL LETTER S + 0xFF54,0x8294, // FULLWIDTH LATIN SMALL LETTER T + 0xFF55,0x8295, // FULLWIDTH LATIN SMALL LETTER U + 0xFF56,0x8296, // FULLWIDTH LATIN SMALL LETTER V + 0xFF57,0x8297, // FULLWIDTH LATIN SMALL LETTER W + 0xFF58,0x8298, // FULLWIDTH LATIN SMALL LETTER X + 0xFF59,0x8299, // FULLWIDTH LATIN SMALL LETTER Y + 0xFF5A,0x829A, // FULLWIDTH LATIN SMALL LETTER Z + 0xFF5B,0x816F, // FULLWIDTH LEFT CURLY BRACKET + 0xFF5C,0x8162, // FULLWIDTH VERTICAL LINE + 0xFF5D,0x8170, // FULLWIDTH RIGHT CURLY BRACKET + 0xFFE3,0x8150, // FULLWIDTH MACRON + 0xFFE5,0x818F // FULLWIDTH YEN SIGN +}; \ No newline at end of file diff --git a/backend/svg.c b/backend/svg.c new file mode 100644 index 00000000..68fb871d --- /dev/null +++ b/backend/svg.c @@ -0,0 +1,625 @@ +/* svg.c - Scalable Vector Graphics */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include +#include "common.h" + +#define SSET "0123456789ABCDEF" + +int svg_plot(struct zint_symbol *symbol) +{ + int i, block_width, latch, r, this_row; + float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0; + FILE *fsvg; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone, main_width; + char textpart[10], addon[6]; + int large_bar_count, comp_offset; + float addon_text_posn; + float scaler = symbol->scale; + float default_text_posn; + int plot_text = 1; + const char *locale = NULL; + + row_height=0; + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + + if((symbol->output_options & BARCODE_STDOUT) != 0) { + fsvg = stdout; + } else { + fsvg = fopen(symbol->outfile, "w"); + } + if(fsvg == NULL) { + strcpy(symbol->errtxt, "Could not open output file"); + return ERROR_FILE_ACCESS; + } + + /* sort out colour options */ + to_upper((unsigned char*)symbol->fgcolour); + to_upper((unsigned char*)symbol->bgcolour); + + if(strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + if(strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed foreground colour target"); + return ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); + if (error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Malformed background colour target"); + return ERROR_INVALID_OPTION; + } + locale = setlocale(LC_ALL, "C"); + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + red_ink = fgred / 256.0; + green_ink = fggrn / 256.0; + blue_ink = fgblu / 256.0; + red_paper = bgred / 256.0; + green_paper = bggrn / 256.0; + blue_paper = bgblu / 256.0; + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for(i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if(symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch(ustrlen(symbol->text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if(symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if(is_extendable(symbol->symbology)) { + for(i = 0; i < ustrlen(symbol->text); i++) { + if (latch == 1) { + addon[r] = symbol->text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if((symbol->show_hrt == 0) || (ustrlen(symbol->text) != 0)) { + plot_text = 0; + } + if(plot_text) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + /* Start writing the header */ + fprintf(fsvg, "\n"); + fprintf(fsvg, "\n"); + if(symbol->symbology != BARCODE_MAXICODE) { + fprintf(fsvg, "width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); + } else { + fprintf(fsvg, "\n"); + if(ustrlen(symbol->text) != 0) { + fprintf(fsvg, " %s\n", symbol->text); + } else { + fprintf(fsvg, " Zint Generated Symbol\n"); + } + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n \n", symbol->fgcolour); + + if(symbol->symbology != BARCODE_MAXICODE) { + fprintf(fsvg, " \n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour); + } else { + fprintf(fsvg, " \n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler), symbol->bgcolour); + } + + if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler; + } else { + default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler; + } + + if(symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode uses hexagons */ + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + + + textoffset = 0.0; + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(fsvg, " \n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + } + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, symbol->bgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, symbol->bgcolour); + for(r = 0; r < symbol->rows; r++) { + for(i = 0; i < symbol->width; i++) { + if(module_is_set(symbol, r, i)) { + /* Dump a hexagon */ + my = r * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + if(r % 2 == 1) { + mx = (2.46 * i) + 1.23 + 1.23; + } else { + mx = (2.46 * i) + 1.23; + } + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + fprintf(fsvg, " \n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); + } + } + } + } + + if(symbol->symbology != BARCODE_MAXICODE) { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + int addon_latch = 0; + + for(r = 0; r < symbol->rows; r++) { + this_row = r; + if(symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for(i = 0; i < r; i++) { + if(symbol->row_height[i] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[i]; + } + } + row_posn += yoffset; + + i = 0; + if(module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { + addon_text_posn = (row_posn + 8.0) * scaler; + addon_latch = 1; + } + if(latch == 1) { + /* a bar */ + if(addon_latch == 0) { + fprintf(fsvg, " \n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler); + } else { + fprintf(fsvg, " \n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); + } + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + /* That's done the actual data area, everything else is human-friendly */ + + xoffset += comp_offset; + row_posn = (row_posn + large_bar_height) * scaler; + + if(plot_text) { + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || + (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch(ustrlen(symbol->text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i]; + } + textpart[4] = '\0'; + textpos = 17; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 4; i++) { + textpart[i] = symbol->text[i + 4]; + } + textpart[4] = '\0'; + textpos = 50; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = xoffset + 86; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 100; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -7; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 24; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 7]; + } + textpart[6] = '\0'; + textpos = 71; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = xoffset + 114; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 128; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if(latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -5; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[5] = '\0'; + textpos = 27; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 6]; + } + textpart[6] = '\0'; + textpos = 68; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textpart[0] = symbol->text[11]; + textpart[1] = '\0'; + textpos = 100; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = xoffset + 116; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 130; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -5; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for(i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 24; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textpart[0] = symbol->text[7]; + textpart[1] = '\0'; + textpos = 55; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch(strlen(addon)) { + case 2: + textpos = xoffset + 70; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 84; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + } + } /* if (plot_text) */ + + xoffset -= comp_offset; + + switch(symbol->symbology) { + case BARCODE_CODABLOCKF: + case BARCODE_HIBC_BLOCKF: + fprintf(fsvg, " \n", xoffset * scaler, 0.0, symbol->width * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", xoffset * scaler, (symbol->height + symbol->border_width) * scaler, symbol->width * scaler, symbol->border_width * scaler); + if(symbol->rows > 1) { + /* row binding */ + for(r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", (xoffset + 11) * scaler, ((r * row_height) + yoffset - 1) * scaler, (symbol->width - 24) * scaler, 2.0 * scaler); + } + } + break; + case BARCODE_MAXICODE: + /* Do nothing! (It's already been done) */ + break; + default: + if((symbol->output_options & BARCODE_BIND) != 0) { + if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + for(r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); + } + } + } + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(fsvg, " \n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } + if((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + } + break; + } + + /* Put the human readable text at the bottom */ + if(plot_text && (textdone == 0)) { + textpos = symbol->width / 2.0; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", symbol->text); + fprintf(fsvg, " \n"); + } + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n"); + + fclose(fsvg); + + if (locale) + setlocale(LC_ALL, locale); + + return error_number; +} + diff --git a/backend/telepen.c b/backend/telepen.c new file mode 100644 index 00000000..5d1ccd95 --- /dev/null +++ b/backend/telepen.c @@ -0,0 +1,157 @@ +/* telepen.c - Handles Telepen and Telepen numeric */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +#define SODIUM "0123456789X" + +#include +#include +#include +#include "common.h" + +static char *TeleTable[] = +{ + "1111111111111111", "1131313111", "33313111", "1111313131", "3111313111", "11333131", "13133131", "111111313111", + "31333111", "1131113131", "33113131", "1111333111", "3111113131", "1113133111", "1311133111", "111111113131", + "3131113111", "11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331", + "31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331", "1311111331", "11111111113111", + "31313311", "1131311131", "33311131", "1111313311", "3111311131", "11333311", "13133311", "111111311131", + "31331131", "1131113311", "33113311", "1111331131", "3111113311", "1113131131", "1311131131", "111111113311", + "3131111131", "1131131311", "33131311", "111131111131", "3111131311", "1133111131", "1313111131", "111111131311", + "3113111311", "113111111131", "3311111131", "111113111311", "311111111131", "111311111311", "131111111311", "11111111111131", + "3131311111", "11313133", "333133", "111131311111", "31113133", "1133311111", "1313311111", "1111113133", + "313333", "113111311111", "3311311111", "11113333", "311111311111", "11131333", "13111333", "11111111311111", + "31311133", "1131331111", "33331111", " 1111311133", "3111331111", "11331133", "13131133", "111111331111", + "3113131111", "1131111133", "33111133", "111113131111", "3111111133", "111311131111", "131111131111", "111111111133", + "31311313", "113131111111", "3331111111", "1111311313", "311131111111", "11331313", "13131313", "11111131111111", + "3133111111", "1131111313", "33111313", "111133111111", "3111111313", "111313111111", "131113111111", "111111111313", + "313111111111", "1131131113", "33131113", "11113111111111","3111131113", "113311111111", "131311111111", "111111131113", + "3113111113", "11311111111111","331111111111","111113111113", "31111111111111","111311111113","131111111113"}; + +int telepen(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ + unsigned int i, count, check_digit; + int error_number; + char dest[512]; /*14 + 30 * 14 + 14 + 14 + 1 ~ 512 */ + + error_number = 0; + + count = 0; + + if(src_len > 30) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + /* Start character */ + strcpy(dest, TeleTable['_']); + + for(i = 0; i < src_len; i++) { + if(source[i] > 127) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "Invalid characters in input data"); + return ERROR_INVALID_DATA; + } + concat(dest, TeleTable[source[i]]); + count += source[i]; + } + + check_digit = 127 - (count % 127); + if(check_digit == 127) { check_digit = 0; } + concat(dest, TeleTable[check_digit]); + + /* Stop character */ + concat(dest, TeleTable['z']); + + expand(symbol, dest); + for(i = 0; i < src_len; i++) { + if(source[i] == '\0') { + symbol->text[i] = ' '; + } else { + symbol->text[i] = source[i]; + } + } + symbol->text[src_len] = '\0'; + return error_number; +} + +int telepen_num(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ + unsigned int i, count, check_digit, glyph; + int error_number, temp_length = src_len; + char dest[1024]; /* 14 + 60 * 14 + 14 + 14 + 1 ~ 1024 */ + unsigned char temp[64]; + + error_number = 0; + count = 0; + + if(temp_length > 60) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + ustrcpy(temp, source); + to_upper(temp); + error_number = is_sane(NEON, temp, temp_length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + /* Add a leading zero if required */ + if ((temp_length % 2) != 0) + { + memmove(temp + 1, temp, temp_length); + temp[0] = '0'; + + temp[++temp_length] = '\0'; + } + + /* Start character */ + strcpy(dest, TeleTable['_']); + + for (i = 0; i < temp_length; i += 2) + { + if(temp[i] == 'X') { + strcpy(symbol->errtxt, "Invalid position of X in Telepen data"); + return ERROR_INVALID_DATA; + } + + if(temp[i + 1] == 'X') { + glyph = ctoi(temp[i]) + 17; + count += glyph; + } else { + glyph = (10 * ctoi(temp[i])) + ctoi(temp[i + 1]); + glyph += 27; + count += glyph; + } + concat(dest, TeleTable[glyph]); + } + + check_digit = 127 - (count % 127); + if(check_digit == 127) { check_digit = 0; } + concat(dest, TeleTable[check_digit]); + + /* Stop character */ + concat(dest, TeleTable['z']); + + expand(symbol, dest); + ustrcpy(symbol->text, temp); + return error_number; +} + diff --git a/backend/upcean.c b/backend/upcean.c new file mode 100644 index 00000000..67301a1a --- /dev/null +++ b/backend/upcean.c @@ -0,0 +1,800 @@ +/* upcean.c - Handles UPC, EAN and ISBN + + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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. +*/ + +#define SODIUM "0123456789+" +#define EAN2 102 +#define EAN5 105 + +#include +#include +#include +#include "common.h" + +/* UPC and EAN tables checked against EN 797:1996 */ + +static char *UPCParity0[10] = {"BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB", + "BABABA", "BABAAB", "BAABAB"}; /* Number set for UPC-E symbol (EN Table 4) */ +static char *UPCParity1[10] = {"AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA", + "ABABAB", "ABABBA", "ABBABA"}; /* Not covered by BS EN 797:1995 */ +static char *EAN2Parity[4] = {"AA", "AB", "BA", "BB"}; /* Number sets for 2-digit add-on (EN Table 6) */ +static char *EAN5Parity[10] = {"BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA", + "ABAAB", "AABAB"}; /* Number set for 5-digit add-on (EN Table 7) */ +static char *EAN13Parity[10] = {"AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB", + "BABBA", "BBABA"}; /* Left hand of the EAN-13 symbol (EN Table 3) */ +static char *EANsetA[10] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213", + "3112"}; /* Representation set A and C (EN Table 1) */ +static char *EANsetB[10] = {"1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121", + "2113"}; /* Representation set B (EN Table 1) */ + +char upc_check(char source[]) +{ /* Calculate the correct check digit for a UPC barcode */ + unsigned int i, count, check_digit; + + count = 0; + + for (i = 0; i < strlen(source); i++) + { + count += ctoi(source[i]); + + if ((i%2) == 0) + { + count += 2 * (ctoi(source[i])); + } + } + + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + return itoc(check_digit); +} + +void upca_draw(char source[], char dest[]) +{ /* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */ + unsigned int i, half_way; + + half_way = strlen(source) / 2; + + /* start character */ + concat (dest, "111"); + + for(i = 0; i <= strlen(source); i++) + { + if (i == half_way) + { + /* middle character - separates manufacturer no. from product no. */ + /* also inverts right hand characters */ + concat(dest, "11111"); + } + + lookup(NEON, EANsetA, source[i], dest); + } + + /* stop character */ + concat (dest, "111"); +} + +void upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) +{ /* Make a UPC A barcode when we haven't been given the check digit */ + int length; + char gtin[15]; + + strcpy(gtin, (char*)source); + length = strlen(gtin); + gtin[length] = upc_check(gtin); + gtin[length + 1] = '\0'; + upca_draw(gtin, dest); + ustrcpy(symbol->text, (unsigned char*)gtin); +} + +void upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) +{ /* UPC E is a zero-compressed version of UPC A */ + unsigned int i, num_system; + char emode, equivalent[12], check_digit, parity[8], temp[8]; + char hrt[9]; + + /* Two number systems can be used - system 0 and system 1 */ + if(ustrlen(source) == 7) { + switch(source[0]) { + case '0': num_system = 0; break; + case '1': num_system = 1; break; + default: num_system = 0; source[0] = '0'; break; + } + strcpy(temp, (char*)source); + strcpy(hrt, (char*)source); + for(i = 1; i <= 7; i++) { + source[i - 1] = temp[i]; + } + } + else { + num_system = 0; + hrt[0] = '0'; + hrt[1] = '\0'; + concat(hrt, (char*)source); + } + + /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */ + emode = source[5]; + for(i = 0; i < 11; i++) { + equivalent[i] = '0'; + } + if(num_system == 1) { equivalent[0] = temp[0]; } + equivalent[1] = source[0]; + equivalent[2] = source[1]; + equivalent[11] = '\0'; + + switch(emode) + { + case '0': + case '1': + case '2': + equivalent[3] = emode; + equivalent[8] = source[2]; + equivalent[9] = source[3]; + equivalent[10] = source[4]; + break; + case '3': + equivalent[3] = source[2]; + equivalent[9] = source[3]; + equivalent[10] = source[4]; + if(((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) { + /* Note 1 - "X3 shall not be equal to 0, 1 or 2" */ + strcpy(symbol->errtxt, "Invalid UPC-E data"); + } + break; + case '4': + equivalent[3] = source[2]; + equivalent[4] = source[3]; + equivalent[10] = source[4]; + if(source[3] == '0') { + /* Note 2 - "X4 shall not be equal to 0" */ + strcpy(symbol->errtxt, "Invalid UPC-E data"); + } + break; + case '5': + case '6': + case '7': + case '8': + case '9': + equivalent[3] = source[2]; + equivalent[4] = source[3]; + equivalent[5] = source[4]; + equivalent[10] = emode; + if(source[4] == '0') { + /* Note 3 - "X5 shall not be equal to 0" */ + strcpy(symbol->errtxt, "Invalid UPC-E data"); + } + break; + } + + /* Get the check digit from the expanded UPCA code */ + + check_digit = upc_check(equivalent); + + /* Use the number system and check digit information to choose a parity scheme */ + if(num_system == 1) { + strcpy(parity, UPCParity1[ctoi(check_digit)]); + } else { + strcpy(parity, UPCParity0[ctoi(check_digit)]); + } + + /* Take all this information and make the barcode pattern */ + + /* start character */ + concat (dest, "111"); + + for(i = 0; i <= ustrlen(source); i++) { + switch(parity[i]) { + case 'A': lookup(NEON, EANsetA, source[i], dest); break; + case 'B': lookup(NEON, EANsetB, source[i], dest); break; + } + } + + /* stop character */ + concat (dest, "111111"); + + hrt[7] = check_digit; + hrt[8] = '\0'; + ustrcpy(symbol->text, (unsigned char*)hrt); +} + + +void add_on(unsigned char source[], char dest[], int mode) +{ /* EAN-2 and EAN-5 add-on codes */ + char parity[6]; + unsigned int i, code_type; + + /* If an add-on then append with space */ + if (mode != 0) + { + concat(dest, "9"); + } + + /* Start character */ + concat (dest, "112"); + + /* Determine EAN2 or EAN5 add-on */ + if(ustrlen(source) == 2) + { + code_type = EAN2; + } + else + { + code_type = EAN5; + } + + /* Calculate parity for EAN2 */ + if(code_type == EAN2) + { + int code_value, parity_bit; + + code_value = (10 * ctoi(source[0])) + ctoi(source[1]); + parity_bit = code_value%4; + strcpy(parity, EAN2Parity[parity_bit]); + } + + if(code_type == EAN5) + { + int values[6], parity_sum, parity_bit; + + for(i = 0; i < 6; i++) + { + values[i] = ctoi(source[i]); + } + + parity_sum = (3 * (values[0] + values[2] + values[4])); + parity_sum += (9 * (values[1] + values[3])); + + parity_bit = parity_sum%10; + strcpy(parity, EAN5Parity[parity_bit]); + } + + for(i = 0; i < ustrlen(source); i++) + { + switch(parity[i]) { + case 'A': lookup(NEON, EANsetA, source[i], dest); break; + case 'B': lookup(NEON, EANsetB, source[i], dest); break; + } + + /* Glyph separator */ + if(i != (ustrlen(source) - 1)) + { + concat (dest, "11"); + } + } +} + + +/* ************************ EAN-13 ****************** */ + +char ean_check(char source[]) +{ /* Calculate the correct check digit for a EAN-13 barcode */ + int i; + unsigned int h, count, check_digit; + + count = 0; + + h = strlen(source); + for (i = h - 1; i >= 0; i--) + { + count += ctoi(source[i]); + + if (!((i%2) == 0)) + { + count += 2 * ctoi(source[i]); + } + } + check_digit = 10 - (count%10); + if (check_digit == 10) { check_digit = 0; } + return itoc(check_digit); +} + +void ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) +{ + unsigned int length, i, half_way; + char parity[6]; + char gtin[15]; + + strcpy(parity, ""); + strcpy(gtin, (char*)source); + + /* Add the appropriate check digit */ + length = strlen(gtin); + gtin[length] = ean_check(gtin); + gtin[length + 1] = '\0'; + + /* Get parity for first half of the symbol */ + lookup(SODIUM, EAN13Parity, gtin[0], parity); + + /* Now get on with the cipher */ + half_way = 7; + + /* start character */ + concat (dest, "111"); + length = strlen(gtin); + for(i = 1; i <= length; i++) + { + if (i == half_way) + { + /* middle character - separates manufacturer no. from product no. */ + /* also inverses right hand characters */ + concat (dest, "11111"); + } + + if(((i > 1) && (i < 7)) && (parity[i - 2] == 'B')) + { + lookup(NEON, EANsetB, gtin[i], dest); + } + else + { + lookup(NEON, EANsetA, gtin[i], dest); + } + } + + /* stop character */ + concat (dest, "111"); + + ustrcpy(symbol->text, (unsigned char*)gtin); +} + +void ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) +{ /* Make an EAN-8 barcode when we haven't been given the check digit */ + /* EAN-8 is basically the same as UPC-A but with fewer digits */ + int length; + char gtin[10]; + + strcpy(gtin, (char*)source); + length = strlen(gtin); + gtin[length] = upc_check(gtin); + gtin[length + 1] = '\0'; + upca_draw(gtin, dest); + ustrcpy(symbol->text, (unsigned char*)gtin); +} + +char isbn13_check(unsigned char source[]) /* For ISBN(13) only */ +{ + unsigned int i, weight, sum, check, h; + + sum = 0; + weight = 1; + h = ustrlen(source) - 1; + + for(i = 0; i < h; i++) + { + sum += ctoi(source[i]) * weight; + if(weight == 1) weight = 3; else weight = 1; + } + + check = sum % 10; + check = 10 - check; + return itoc(check); +} + +char isbn_check(unsigned char source[]) /* For ISBN(10) and SBN only */ +{ + unsigned int i, weight, sum, check, h; + char check_char; + + sum = 0; + weight = 1; + h = ustrlen(source) - 1; + + for(i = 0; i < h; i++) + { + sum += ctoi(source[i]) * weight; + weight++; + } + + check = sum % 11; + check_char = itoc(check); + if(check == 10) { check_char = 'X'; } + return check_char; +} + +int isbn(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char dest[]) /* Make an EAN-13 barcode from an SBN or ISBN */ +{ + int i, error_number; + char check_digit; + + to_upper(source); + error_number = is_sane("0123456789X", source, src_len); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in input"); + return error_number; + } + + /* Input must be 9, 10 or 13 characters */ + if(((src_len < 9) || (src_len > 13)) || ((src_len > 10) && (src_len < 13))) + { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + + if(src_len == 13) /* Using 13 character ISBN */ + { + if(!(((source[0] == '9') && (source[1] == '7')) && + ((source[2] == '8') || (source[2] == '9')))) + { + strcpy(symbol->errtxt, "Invalid ISBN"); + return ERROR_INVALID_DATA; + } + + check_digit = isbn13_check(source); + if (source[src_len - 1] != check_digit) + { + strcpy(symbol->errtxt, "Incorrect ISBN check"); + return ERROR_INVALID_CHECK; + } + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + if(src_len == 10) /* Using 10 digit ISBN */ + { + check_digit = isbn_check(source); + if(check_digit != source[src_len - 1]) + { + strcpy(symbol->errtxt, "Incorrect ISBN check"); + return ERROR_INVALID_CHECK; + } + for(i = 13; i > 0; i--) + { + source[i] = source[i - 3]; + } + source[0] = '9'; + source[1] = '7'; + source[2] = '8'; + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + if(src_len == 9) /* Using 9 digit SBN */ + { + /* Add leading zero */ + for(i = 10; i > 0; i--) + { + source[i] = source[i - 1]; + } + source[0] = '0'; + + /* Verify check digit */ + check_digit = isbn_check(source); + if(check_digit != source[ustrlen(source) - 1]) + { + strcpy(symbol->errtxt, "Incorrect SBN check"); + return ERROR_INVALID_CHECK; + } + + /* Convert to EAN-13 number */ + for(i = 13; i > 0; i--) + { + source[i] = source[i - 3]; + } + source[0] = '9'; + source[1] = '7'; + source[2] = '8'; + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + return 0; +} + +void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { + /* Add leading zeroes to EAN and UPC strings */ + unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; + int with_addon = 0; + int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; + + h = ustrlen(source); + for(i = 0; i < h; i++) { + if(source[i] == '+') { + with_addon = 1; + } else { + if(with_addon == 0) { + first_len++; + } else { + second_len++; + } + } + } + + ustrcpy(first_part, (unsigned char *)""); + ustrcpy(second_part, (unsigned char *)""); + ustrcpy(zfirst_part, (unsigned char *)""); + ustrcpy(zsecond_part, (unsigned char *)""); + + /* Split input into two strings */ + for(i = 0; i < first_len; i++) { + first_part[i] = source[i]; + first_part[i + 1] = '\0'; + } + + for(i = 0; i < second_len; i++) { + second_part[i] = source[i + first_len + 1]; + second_part[i + 1] = '\0'; + } + + /* Calculate target lengths */ + if(second_len <= 5) { zsecond_len = 5; } + if(second_len <= 2) { zsecond_len = 2; } + if(second_len == 0) { zsecond_len = 0; } + switch(symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + if(first_len <= 12) { zfirst_len = 12; } + if(first_len <= 7) { zfirst_len = 7; } + if(second_len == 0) { + if(first_len <= 5) { zfirst_len = 5; } + if(first_len <= 2) { zfirst_len = 2; } + } + break; + case BARCODE_UPCA: + case BARCODE_UPCA_CC: + zfirst_len = 11; + break; + case BARCODE_UPCE: + case BARCODE_UPCE_CC: + if(first_len == 7) { zfirst_len = 7; } + if(first_len <= 6) { zfirst_len = 6; } + break; + case BARCODE_ISBNX: + if(first_len <= 9) { zfirst_len = 9; } + break; + } + + + /* Add leading zeroes */ + for(i = 0; i < (zfirst_len - first_len); i++) { + uconcat(zfirst_part, (unsigned char *)"0"); + } + uconcat(zfirst_part, first_part); + for(i = 0; i < (zsecond_len - second_len); i++) { + uconcat(zsecond_part, (unsigned char *)"0"); + } + uconcat(zsecond_part, second_part); + + /* Copy adjusted data back to local_source */ + uconcat(local_source, zfirst_part); + if(zsecond_len != 0) { + uconcat(local_source, (unsigned char *)"+"); + uconcat(local_source, zsecond_part); + } +} + +int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) +{ + /* splits string to parts before and after '+' parts */ + unsigned char first_part[20] = { 0 }, second_part[20] = { 0 }, dest[1000] = { 0 }; + unsigned char local_source[20] = { 0 }; + unsigned int latch, reader, writer, with_addon; + int error_number, i; + + + with_addon = FALSE; + latch = FALSE; + writer = 0; + + if(src_len > 19) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + if(symbol->symbology != BARCODE_ISBNX) { + /* ISBN has it's own checking routine */ + error_number = is_sane("0123456789+", source, src_len); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + } else { + error_number = is_sane("0123456789Xx", source, src_len); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in input"); + return error_number; + } + } + + + /* Add leading zeroes */ + ustrcpy(local_source, (unsigned char *)""); + if(symbol->symbology == BARCODE_ISBNX) { + to_upper(local_source); + } + + ean_leading_zeroes(symbol, source, local_source); + + for(reader = 0; reader <= ustrlen(local_source); reader++) + { + if(source[reader] == '+') { with_addon = TRUE; } + } + + reader = 0; + if(with_addon) { + do { + if(local_source[reader] == '+') { + first_part[writer] = '\0'; + latch = TRUE; + reader++; + writer = 0; + } + + if(latch) { + second_part[writer] = local_source[reader]; + reader++; + writer++; + } else { + first_part[writer] = local_source[reader]; + reader++; + writer++; + } + } while (reader <= ustrlen(local_source)); + } else { + strcpy((char*)first_part, (char*)local_source); + } + + + switch(symbol->symbology) + { + case BARCODE_EANX: + switch(ustrlen(first_part)) + { + case 2: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; + case 5: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; + case 7: ean8(symbol, first_part, (char*)dest); break; + case 12: ean13(symbol, first_part, (char*)dest); break; + default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; + } + break; + case BARCODE_EANX_CC: + switch(ustrlen(first_part)) + { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ + case 7: set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 67); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 68); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 1, 67); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + ean8(symbol, first_part, (char*)dest); break; + case 12:set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 95); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 96); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 95); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + ean13(symbol, first_part, (char*)dest); break; + default: strcpy(symbol->errtxt, "Invalid length EAN input"); return ERROR_TOO_LONG; break; + } + break; + case BARCODE_UPCA: + if(ustrlen(first_part) == 11) { + upca(symbol, first_part, (char*)dest); + } else { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + break; + case BARCODE_UPCA_CC: + if(ustrlen(first_part) == 11) { + set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 95); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 96); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 95); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + upca(symbol, first_part, (char*)dest); + } else { + strcpy(symbol->errtxt, "UPCA input wrong length"); + return ERROR_TOO_LONG; + } + break; + case BARCODE_UPCE: + if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { + upce(symbol, first_part, (char*)dest); + } else { + strcpy(symbol->errtxt, "Input wrong length"); + return ERROR_TOO_LONG; + } + break; + case BARCODE_UPCE_CC: + if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { + set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 51); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 52); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 51); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + upce(symbol, first_part, (char*)dest); + } else { + strcpy(symbol->errtxt, "UPCE input wrong length"); + return ERROR_TOO_LONG; + } + break; + case BARCODE_ISBNX: + error_number = isbn(symbol, first_part, ustrlen(first_part), (char*)dest); + if(error_number > 4) { + return error_number; + } + break; + } + switch(ustrlen(second_part)) + { + case 0: break; + case 2: + add_on(second_part, (char*)dest, 1); + uconcat(symbol->text, (unsigned char*)"+"); + uconcat(symbol->text, second_part); + break; + case 5: + add_on(second_part, (char*)dest, 1); + uconcat(symbol->text, (unsigned char*)"+"); + uconcat(symbol->text, second_part); + break; + default: + strcpy(symbol->errtxt, "Invalid length input"); + return ERROR_TOO_LONG; + break; + } + + expand(symbol, (char*)dest); + + switch(symbol->symbology) { + case BARCODE_EANX_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* shift the symbol to the right one space to allow for separator bars */ + for(i = (symbol->width + 1); i >= 1; i--) { + if(module_is_set(symbol, symbol->rows - 1, i - 1)) { + set_module(symbol, symbol->rows - 1, i); + } else { + unset_module(symbol, symbol->rows - 1, i); + } + } + unset_module(symbol, symbol->rows - 1, 0); + symbol->width += 2; + break; + } + + + if((symbol->errtxt[0] == 'w') && (error_number == 0)) { + error_number = 1; /* flag UPC-E warnings */ + } + return error_number; +} + + + + diff --git a/backend/zint.h b/backend/zint.h new file mode 100644 index 00000000..71c3fafe --- /dev/null +++ b/backend/zint.h @@ -0,0 +1,206 @@ +/* zint.h - definitions for libzint + + libzint - the open source barcode library + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +#ifndef ZINT_H +#define ZINT_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct zint_symbol { + int symbology; + int height; + int whitespace_width; + int border_width; + int output_options; + char fgcolour[10]; + char bgcolour[10]; + char outfile[256]; + float scale; + int option_1; + int option_2; + int option_3; + int show_hrt; + int input_mode; + unsigned char text[128]; + int rows; + int width; + char primary[128]; + unsigned char encoded_data[178][143]; + int row_height[178]; /* Largest symbol is 177x177 QR Code */ + char errtxt[100]; + char *bitmap; + int bitmap_width; + int bitmap_height; +}; + +/* Tbarcode 7 codes */ +#define BARCODE_CODE11 1 +#define BARCODE_C25MATRIX 2 +#define BARCODE_C25INTER 3 +#define BARCODE_C25IATA 4 +#define BARCODE_C25LOGIC 6 +#define BARCODE_C25IND 7 +#define BARCODE_CODE39 8 +#define BARCODE_EXCODE39 9 +#define BARCODE_EANX 13 +#define BARCODE_EAN128 16 +#define BARCODE_CODABAR 18 +#define BARCODE_CODE128 20 +#define BARCODE_DPLEIT 21 +#define BARCODE_DPIDENT 22 +#define BARCODE_CODE16K 23 +#define BARCODE_CODE49 24 +#define BARCODE_CODE93 25 +#define BARCODE_FLAT 28 +#define BARCODE_RSS14 29 +#define BARCODE_RSS_LTD 30 +#define BARCODE_RSS_EXP 31 +#define BARCODE_TELEPEN 32 +#define BARCODE_UPCA 34 +#define BARCODE_UPCE 37 +#define BARCODE_POSTNET 40 +#define BARCODE_MSI_PLESSEY 47 +#define BARCODE_FIM 49 +#define BARCODE_LOGMARS 50 +#define BARCODE_PHARMA 51 +#define BARCODE_PZN 52 +#define BARCODE_PHARMA_TWO 53 +#define BARCODE_PDF417 55 +#define BARCODE_PDF417TRUNC 56 +#define BARCODE_MAXICODE 57 +#define BARCODE_QRCODE 58 +#define BARCODE_CODE128B 60 +#define BARCODE_AUSPOST 63 +#define BARCODE_AUSREPLY 66 +#define BARCODE_AUSROUTE 67 +#define BARCODE_AUSREDIRECT 68 +#define BARCODE_ISBNX 69 +#define BARCODE_RM4SCC 70 +#define BARCODE_DATAMATRIX 71 +#define BARCODE_EAN14 72 +#define BARCODE_CODABLOCKF 74 +#define BARCODE_NVE18 75 +#define BARCODE_JAPANPOST 76 +#define BARCODE_KOREAPOST 77 +#define BARCODE_RSS14STACK 79 +#define BARCODE_RSS14STACK_OMNI 80 +#define BARCODE_RSS_EXPSTACK 81 +#define BARCODE_PLANET 82 +#define BARCODE_MICROPDF417 84 +#define BARCODE_ONECODE 85 +#define BARCODE_PLESSEY 86 + +/* Tbarcode 8 codes */ +#define BARCODE_TELEPEN_NUM 87 +#define BARCODE_ITF14 89 +#define BARCODE_KIX 90 +#define BARCODE_AZTEC 92 +#define BARCODE_DAFT 93 +#define BARCODE_MICROQR 97 + +/* Tbarcode 9 codes */ +#define BARCODE_HIBC_128 98 +#define BARCODE_HIBC_39 99 +#define BARCODE_HIBC_DM 102 +#define BARCODE_HIBC_QR 104 +#define BARCODE_HIBC_PDF 106 +#define BARCODE_HIBC_MICPDF 108 +#define BARCODE_HIBC_BLOCKF 110 +#define BARCODE_HIBC_AZTEC 112 + +/* Zint specific */ +#define BARCODE_AZRUNE 128 +#define BARCODE_CODE32 129 +#define BARCODE_EANX_CC 130 +#define BARCODE_EAN128_CC 131 +#define BARCODE_RSS14_CC 132 +#define BARCODE_RSS_LTD_CC 133 +#define BARCODE_RSS_EXP_CC 134 +#define BARCODE_UPCA_CC 135 +#define BARCODE_UPCE_CC 136 +#define BARCODE_RSS14STACK_CC 137 +#define BARCODE_RSS14_OMNI_CC 138 +#define BARCODE_RSS_EXPSTACK_CC 139 +#define BARCODE_CHANNEL 140 +#define BARCODE_CODEONE 141 +#define BARCODE_GRIDMATRIX 142 + +#define BARCODE_NO_ASCII 1 +#define BARCODE_BIND 2 +#define BARCODE_BOX 4 +#define BARCODE_STDOUT 8 +#define READER_INIT 16 + +#define DATA_MODE 0 +#define UNICODE_MODE 1 +#define GS1_MODE 2 +#define KANJI_MODE 3 +#define SJIS_MODE 4 + +#define DM_SQUARE 100 + +#define WARN_INVALID_OPTION 2 +#define ERROR_TOO_LONG 5 +#define ERROR_INVALID_DATA 6 +#define ERROR_INVALID_CHECK 7 +#define ERROR_INVALID_OPTION 8 +#define ERROR_ENCODING_PROBLEM 9 +#define ERROR_FILE_ACCESS 10 +#define ERROR_MEMORY 11 + +#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER) +# if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL) +# define ZINT_EXTERN __declspec(dllexport) +# elif defined(ZINT_DLL) +# define ZINT_EXTERN __declspec(dllimport) +# else +# define ZINT_EXTERN extern +# endif +#else +# define ZINT_EXTERN extern +#endif + +ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); +ZINT_EXTERN void ZBarcode_Clear(struct zint_symbol *symbol); +ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol); + +ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input, int length); +ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename); +ZINT_EXTERN int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); + +ZINT_EXTERN int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle); + +ZINT_EXTERN int ZBarcode_ValidID(int symbol_id); + +/* Depreciated */ +ZINT_EXTERN int ZBarcode_Print_Rotated(struct zint_symbol *symbol, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char *input, int rotate_angle); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ZINT_H */ diff --git a/backend_qt4/CMakeLists.txt b/backend_qt4/CMakeLists.txt new file mode 100644 index 00000000..98d529af --- /dev/null +++ b/backend_qt4/CMakeLists.txt @@ -0,0 +1,22 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(QZint) + +include_directories(BEFORE "${CMAKE_SOURCE_DIR}/backend" ) + +set(QZint_SRCS qzint.cpp) + +add_library(QZint SHARED ${QZint_SRCS}) + +set_target_properties(QZint PROPERTIES SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}" + VERSION ${ZINT_VERSION}) + +add_dependencies(QZint zint) + +link_directories( "${CMAKE_BINARY_DIR}/backend" ) + +target_link_libraries(QZint zint ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} ) + +install(TARGETS QZint ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(FILES qzint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) diff --git a/backend_qt4/QtZint2.sln b/backend_qt4/QtZint2.sln new file mode 100644 index 00000000..8a7c50cb --- /dev/null +++ b/backend_qt4/QtZint2.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtZint2", "QtZint2.vcproj", "{54ADAB01-7047-3ED1-B8D2-7AC84B1C5090}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {54ADAB01-7047-3ED1-B8D2-7AC84B1C5090}.Debug|Win32.ActiveCfg = Debug|Win32 + {54ADAB01-7047-3ED1-B8D2-7AC84B1C5090}.Debug|Win32.Build.0 = Debug|Win32 + {54ADAB01-7047-3ED1-B8D2-7AC84B1C5090}.Release|Win32.ActiveCfg = Release|Win32 + {54ADAB01-7047-3ED1-B8D2-7AC84B1C5090}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/backend_qt4/QtZint2.vcproj b/backend_qt4/QtZint2.vcproj new file mode 100644 index 00000000..ecc26286 --- /dev/null +++ b/backend_qt4/QtZint2.vcproj @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend_qt4/backend_qt4.pro b/backend_qt4/backend_qt4.pro new file mode 100644 index 00000000..6fbfd44a --- /dev/null +++ b/backend_qt4/backend_qt4.pro @@ -0,0 +1,110 @@ +TEMPLATE = lib + +CONFIG += dll + +macx{ + CONFIG -= dll + CONFIG += lib_bundle +} + +TARGET = QtZint + +INCLUDEPATH += ../backend + +#EDIT THIS !!!! +DEFINES += NO_PNG NO_QR ZINT_VERSION="2.3.0" + +!contains(DEFINES, NO_PNG) { + SOURCES += ../backend/png.c + LIBS += -lpng +} + +contains(DEFINES, QR_SYSTEM){ + LIBS += -lqrencode +} + +contains(DEFINES, QR){ + +INCLUDEPATH += qrencode + +HEADERS += qrencode/bitstream.h \ + qrencode/mask.h \ + qrencode/qrencode.h \ + qrencode/qrencode_inner.h \ + qrencode/qrinput.h \ + qrencode/qrspec.h \ + qrencode/rscode.h \ + qrencode/split.h + +SOURCES += qrencode/bitstream.c \ + qrencode/mask.c \ + qrencode/qrencode.c \ + qrencode/qrinput.c \ + qrencode/qrspec.c \ + qrencode/rscode.c \ + qrencode/split.c +} + +HEADERS += ../backend/aztec.h \ + ../backend/code49.h \ + ../backend/common.h \ + ../backend/composite.h \ + ../backend/dm200.h \ + ../backend/dmatrix.h \ + ../backend/font.h \ + ../backend/gs1.h \ + ../backend/large.h \ + ../backend/maxicode.h \ + ../backend/maxipng.h \ + ../backend/micqr.h \ + ../backend/pdf417.h \ + ../backend/reedsol.h \ + ../backend/rss.h \ + ../backend/sjis.h \ + ../backend/zint.h \ + qzint.h + +SOURCES += ../backend/2of5.c \ + ../backend/auspost.c \ + ../backend/aztec.c \ + ../backend/blockf.c \ + ../backend/code.c \ + ../backend/code128.c \ + ../backend/code16k.c \ + ../backend/code49.c \ + ../backend/common.c \ + ../backend/composite.c \ + ../backend/dm200.c \ + ../backend/dmatrix.c \ + ../backend/gs1.c \ + ../backend/imail.c \ + ../backend/large.c \ + ../backend/library.c \ + ../backend/maxicode.c \ + ../backend/medical.c \ + ../backend/micqr.c \ + ../backend/pdf417.c \ + ../backend/plessey.c \ + ../backend/postal.c \ + ../backend/ps.c \ + ../backend/reedsol.c \ + ../backend/rss.c \ + ../backend/svg.c \ + ../backend/telepen.c \ + ../backend/upcean.c \ + ../backend/qr.c \ + ../backend/dllversion.c \ + ../backend/code1.c \ + qzint.cpp + +VERSION = 2.3.0 + +#DESTDIR = . + +include.path = $$[ZINT_INSTALL_HEADERS] +include.files = ../backend/zint.h qzint.h + +target.path = $$[ZINT_INSTALL_LIBS] + +INSTALLS += target include + diff --git a/backend_qt4/backend_vc8.pro b/backend_qt4/backend_vc8.pro new file mode 100644 index 00000000..1342100e --- /dev/null +++ b/backend_qt4/backend_vc8.pro @@ -0,0 +1,74 @@ +win32 { + TEMPLATE = vclib + CONFIG += staticlib debug-and-release +} + +TARGET = QtZint2 +VERSION = 2.3.0 + +QMAKE_CFLAGS += /TP /wd4018 /wd4244 /wd4305 +QMAKE_CXXFLAGS += /TP /wd4018 /wd4244 /wd4305 + +INCLUDEPATH += ../backend d:\opt\include + +DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$VERSION\\\" + +!contains(DEFINES, NO_PNG) { + SOURCES += ../backend/png.c +} + +HEADERS += ../backend/aztec.h \ + ../backend/code1.h \ + ../backend/code49.h \ + ../backend/common.h \ + ../backend/composite.h \ + ../backend/dm200.h \ + ../backend/dmatrix.h \ + ../backend/font.h \ + ../backend/gb2312.h \ + ../backend/gridmtx.h \ + ../backend/gs1.h \ + ../backend/large.h \ + ../backend/maxicode.h \ + ../backend/maxipng.h \ + ../backend/ms_stdint.h \ + ../backend/pdf417.h \ + ../backend/qr.h \ + ../backend/reedsol.h \ + ../backend/rss.h \ + ../backend/sjis.h \ + ../backend/zint.h \ + qzint.h + +SOURCES += ../backend/2of5.c \ + ../backend/auspost.c \ + ../backend/aztec.c \ + ../backend/blockf.c \ + ../backend/code.c \ + ../backend/code1.c \ + ../backend/code128.c \ + ../backend/code16k.c \ + ../backend/code49.c \ + ../backend/common.c \ + ../backend/composite.c \ + ../backend/dm200.c \ + ../backend/dmatrix.c \ + ../backend/gridmtx.c \ + ../backend/gs1.c \ + ../backend/imail.c \ + ../backend/large.c \ + ../backend/library.c \ + ../backend/maxicode.c \ + ../backend/medical.c \ + ../backend/pdf417.c \ + ../backend/plessey.c \ + ../backend/postal.c \ + ../backend/ps.c \ + ../backend/qr.c \ + ../backend/reedsol.c \ + ../backend/rss.c \ + ../backend/svg.c \ + ../backend/telepen.c \ + ../backend/upcean.c \ + qzint.cpp + diff --git a/backend_qt4/qzint.cpp b/backend_qt4/qzint.cpp new file mode 100644 index 00000000..21311447 --- /dev/null +++ b/backend_qt4/qzint.cpp @@ -0,0 +1,717 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * * + * 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, see . * + ***************************************************************************/ + +#include "qzint.h" +#include + +namespace Zint +{ + +static const qreal maxi_diagonal=11; +static const qreal maxi_width=1.73205807568877*maxi_diagonal/2; +static const char* fontstyle="Arial"; +static const int fontPixelSizeSmall=6; +static const int fontPixelSizeLarge=8; + +QZint::QZint() +{ + m_symbol=BARCODE_CODE128; + m_height=50; + m_border=NO_BORDER; + m_borderWidth=1; + m_securityLevel=-1; + m_pdf417CodeWords=928; + m_fgColor=Qt::black; + m_bgColor=Qt::white; + m_zintSymbol=0; + m_error=0; + m_input_mode = UNICODE_MODE; + m_scale = 1.0; + m_option_3 = 0; + m_hidetext = FALSE; +} + +QZint::~QZint() +{ + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); +} + +void QZint::encode() +{ + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); + + m_lastError.clear(); + m_zintSymbol = ZBarcode_Create(); + m_zintSymbol->output_options=m_border; + m_zintSymbol->symbology=m_symbol; + m_zintSymbol->height=m_height; + m_zintSymbol->whitespace_width=m_whitespace; + m_zintSymbol->border_width=m_borderWidth; + m_zintSymbol->option_1=m_securityLevel; + m_zintSymbol->input_mode = m_input_mode; + m_zintSymbol->option_2=m_width; + if(m_hidetext) { + m_zintSymbol->show_hrt = 0; + } else { + m_zintSymbol->show_hrt = 1; + } + if(m_symbol == BARCODE_PDF417) { + m_zintSymbol->option_3=m_pdf417CodeWords; + } else { + m_zintSymbol->option_3 = m_option_3; + } + QByteArray bstr=m_text.toUtf8(); + QByteArray pstr=m_primaryMessage.left(99).toAscii(); + strcpy(m_zintSymbol->primary,pstr.data()); + int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length()); + if (error > WARN_INVALID_OPTION) + m_lastError=m_zintSymbol->errtxt; + + if (m_zintSymbol->symbology == BARCODE_MAXICODE) + m_zintSymbol->height = 33; + + switch(m_zintSymbol->output_options) { + case 0: m_border = NO_BORDER; break; + case 2: m_border = BIND; break; + case 4: m_border = BOX; break; + } + m_borderWidth = (BorderType)m_zintSymbol->border_width; + m_whitespace = m_zintSymbol->whitespace_width; +} + +int QZint::symbol() +{ + return m_symbol; +} +void QZint::setSymbol(int symbol) +{ + m_symbol=symbol; +} + +void QZint::setInputMode(int input_mode) +{ + m_input_mode = input_mode; +} + +QString QZint::text() +{ + return m_text; +} +void QZint::setText(const QString & text) +{ + m_text=text; +} + +QString QZint::primaryMessage() +{ + return m_primaryMessage; +} +void QZint::setPrimaryMessage(const QString & primaryMessage) +{ + m_primaryMessage=primaryMessage; +} + +int QZint::height() +{ + encode(); + return (m_zintSymbol->height+(m_border!=NO_BORDER)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1); +} + +void QZint::setHeight(int height) +{ + m_height=height; +} + +void QZint::setWidth(int width) +{ + m_width=width; +} + +void QZint::setOption3(int option) +{ + m_option_3 = option; +} + +int QZint::width() +{ + encode(); + return (m_zintSymbol->width+(m_border==BOX)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1); +} + +float QZint::scale() +{ + return m_scale; +} + +void QZint::setScale(float scale) +{ + m_scale = scale; +} + +QColor QZint::fgColor() +{ + return m_fgColor; +} +void QZint::setFgColor(const QColor & fgColor) +{ + m_fgColor=fgColor; +} + +QColor QZint::bgColor() +{ + return m_bgColor; +} +void QZint::setBgColor(const QColor & bgColor) +{ + m_bgColor=bgColor; +} + +QZint::BorderType QZint::borderType() +{ + return m_border; +} +void QZint::setBorderType(BorderType border) +{ + m_border=border; +} + +int QZint::borderWidth() +{ + return m_borderWidth; +} +void QZint::setBorderWidth(int boderWidth) +{ + if (boderWidth<1 || boderWidth>16) + boderWidth=1; + m_borderWidth=boderWidth; +} + +void QZint::setWhitespace(int whitespace) +{ + m_whitespace = whitespace; +} + +int QZint::pdf417CodeWords() +{ + return m_pdf417CodeWords; +} +void QZint::setPdf417CodeWords(int pdf417CodeWords) +{ + m_pdf417CodeWords=pdf417CodeWords; +} + +int QZint::securityLevel() +{ + return m_securityLevel; +} +void QZint::setSecurityLevel(int securityLevel) +{ + m_securityLevel=securityLevel; +} + +QString QZint::error_message() +{ + return m_lastError; +} + +int QZint::mode() +{ + return m_securityLevel; +} +void QZint::setMode(int securityLevel) +{ + m_securityLevel=securityLevel; +} + +void QZint::setHideText(bool hide) +{ + m_hidetext = hide; +} + +bool QZint::save_to_file(QString filename) +{ + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); + + QString fg_colour_hash = m_fgColor.name(); + QString bg_colour_hash = m_bgColor.name(); + + m_lastError.clear(); + m_zintSymbol = ZBarcode_Create(); + m_zintSymbol->output_options=m_border; + m_zintSymbol->symbology=m_symbol; + m_zintSymbol->height=m_height; + m_zintSymbol->whitespace_width=m_whitespace; + m_zintSymbol->border_width=m_borderWidth; + m_zintSymbol->option_1=m_securityLevel; + m_zintSymbol->input_mode = m_input_mode; + m_zintSymbol->option_2=m_width; + if(m_hidetext) { + m_zintSymbol->show_hrt = 0; + } else { + m_zintSymbol->show_hrt = 1; + } + if(m_symbol == BARCODE_PDF417) { + m_zintSymbol->option_3=m_pdf417CodeWords; + } else { + m_zintSymbol->option_3 = m_option_3; + } + m_zintSymbol->scale=m_scale; + QByteArray bstr=m_text.toUtf8(); + QByteArray pstr=m_primaryMessage.left(99).toAscii(); + QByteArray fstr=filename.left(255).toAscii(); + strcpy(m_zintSymbol->primary,pstr.data()); + strcpy(m_zintSymbol->outfile,fstr.data()); + QByteArray fgcol=fg_colour_hash.right(6).toAscii(); + QByteArray bgcol=bg_colour_hash.right(6).toAscii(); + strcpy(m_zintSymbol->fgcolour,fgcol.data()); + strcpy(m_zintSymbol->bgcolour,bgcol.data()); + int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length()); + if (error > WARN_INVALID_OPTION) + m_lastError=m_zintSymbol->errtxt; + error = ZBarcode_Print(m_zintSymbol, 0); + if (error > WARN_INVALID_OPTION) + m_lastError=m_zintSymbol->errtxt; + if(error == 0) { return true; } else { return false; } +} + +int QZint::module_set(int y_coord, int x_coord) +{ + int x_char, x_sub, result; + + x_char = x_coord / 7; + x_sub = x_coord % 7; + result = 0; + + switch(x_sub) { + case 0: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x01) != 0) { result = 1; } break; + case 1: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x02) != 0) { result = 1; } break; + case 2: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x04) != 0) { result = 1; } break; + case 3: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x08) != 0) { result = 1; } break; + case 4: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x10) != 0) { result = 1; } break; + case 5: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x20) != 0) { result = 1; } break; + case 6: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x40) != 0) { result = 1; } break; + } + + return result; +} + +void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode) +{ + encode(); + bool textdone; + int comp_offset = 0, xoffset = m_whitespace, j, main_width = 0, addon_text_height = 0; + int yoffset = 0; + QString caption = QString::fromUtf8((const char *)m_zintSymbol->text, -1); + QFont fontSmall(fontstyle); + fontSmall.setPixelSize(fontPixelSizeSmall); + QFont fontLarge(fontstyle); + fontLarge.setPixelSize(fontPixelSizeLarge); + + if (m_lastError.length()) + { + painter.setFont(fontLarge); + painter.drawText(paintRect,Qt::AlignCenter,m_lastError); + return; + } + + painter.save(); + painter.setClipRect(paintRect,Qt::IntersectClip); + qreal xtr=paintRect.x(); + qreal ytr=paintRect.y(); + + int zrow_height=m_zintSymbol->height; + int zrows=0; + for (int i=0;irows;i++) + { + zrow_height-=m_zintSymbol->row_height[i]; + if (!m_zintSymbol->row_height[i]) + zrows++; + } + if (zrows) + { + zrow_height/=zrows; + for (int i=0;irows;i++) + if (!m_zintSymbol->row_height[i]) + m_zintSymbol->row_height[i]=zrow_height; + } + else + m_zintSymbol->height-=zrow_height; + + + qreal gwidth=m_zintSymbol->width; + qreal gheight=m_zintSymbol->height; + if (m_zintSymbol->symbology == BARCODE_MAXICODE) + { + gheight*=(maxi_width); + gwidth*=(maxi_width+1); + } + + qreal xsf=1; + qreal ysf=1; + qreal textoffset = 0; + + gwidth+=((m_border==BOX)?m_borderWidth*2:0); + gheight+=((m_border!=NO_BORDER)?m_borderWidth*2:0); + if(QString((const char*)m_zintSymbol->text).isEmpty() == false) { + textoffset = 9; + gheight += textoffset; + } else { + textoffset = 0; + } + gwidth+=m_zintSymbol->whitespace_width*2; + switch(mode) + { + case IgnoreAspectRatio: + xsf=(qreal)paintRect.width()/gwidth; + ysf=(qreal)paintRect.height()/gheight; + break; + + case KeepAspectRatio: + if (paintRect.width()/gwidthsymbology != BARCODE_MAXICODE) { + /* Draw boundary bars or boxes around the symbol */ + switch(m_border) + { + case BOX: + painter.fillRect(0,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor)); + painter.fillRect(m_zintSymbol->width + xoffset + xoffset + m_borderWidth,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor)); + painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth,m_borderWidth,QBrush(m_fgColor)); + painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth,QBrush(m_fgColor)); + painter.translate(m_borderWidth+m_zintSymbol->whitespace_width,m_borderWidth); + yoffset = m_borderWidth; + break; + case BIND: + painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset,m_borderWidth,QBrush(m_fgColor)); + painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset, m_borderWidth,QBrush(m_fgColor)); + painter.translate(m_zintSymbol->whitespace_width,m_borderWidth); + yoffset = m_borderWidth; + break; + + default: + painter.translate(m_zintSymbol->whitespace_width,0); + break;; + } + } + + while(!(module_set(m_zintSymbol->rows - 1, comp_offset))) { + comp_offset++; + } + xoffset = comp_offset; + + /* Set up some values for displaying EAN and UPC symbols correctly */ + main_width = m_zintSymbol->width; + if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) + || (m_zintSymbol->symbology == BARCODE_ISBNX)) { + switch(caption.size()) { + case 13: /* EAN 13 */ + case 16: + case 19: + if(m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + break; + } + } + + if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { + if(m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + } + + if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { + if(m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 51 + comp_offset; + } + + p.setWidth(1); + painter.setPen(p); + + if (m_zintSymbol->symbology == BARCODE_MAXICODE) + { + /* Draw Maxicode with hexagons */ + painter.save(); + painter.setRenderHint(QPainter::Antialiasing); + for (int r=0;rrows;r++) + { + for (int c=0;cwidth;c++) + { + if (module_set(r, c)) + { + qreal col=(qreal)c*(maxi_width+1)+(r%2)*((maxi_width+1)/2); + qreal row=(qreal)r*(maxi_width+1)*0.868; + QPainterPath pt; + pt.moveTo(col+maxi_width/2, row); + pt.lineTo(col+maxi_width, row+maxi_diagonal/4); + pt.lineTo(col+maxi_width, row+(maxi_diagonal-maxi_diagonal/4)); + pt.lineTo(col+maxi_width/2, row+maxi_diagonal); + pt.lineTo(col, row+(maxi_diagonal-maxi_diagonal/4)); + pt.lineTo(col, row+maxi_diagonal/4); + pt.lineTo(col+maxi_width/2, row); + painter.fillPath(pt,QBrush(m_fgColor)); + } + } + } + p.setWidth(maxi_width); + painter.setPen(p); + const qreal w=maxi_width+1; + painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w,w); + painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*1.5,w+w*1.5); + painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*3,w+w*3); + painter.restore(); + } + else + { + /* Draw all other symbols with rectangles */ + int y=0; + for (int row=0;rowrows;row++) + { + for (int i=0;iwidth;i++) { + if (module_set(row, i)) + { + int ed = module_set(row, i); + int linewidth=0; + for (int j=i;jwidth;j++,linewidth++) + if (ed != module_set(row, j)) + break; + QColor color; + /* switch(ed) + { + case 'R': + color=qRgb(0xff,0x00,0x00); + break; + + case 'G': + color=qRgb(0x00,0xff,0x00); + break; + + case 'B': + color=qRgb(0x00,0x00,0xff); + break; + + case 'C': + color=qRgb(0x00,0xff,0xff); + break; + + case 'M': + color=qRgb(0xff,0x00,0xff); + break; + + case 'Y': + color=qRgb(0xff,0xff,0x00); + break; + + default: */ + color=m_fgColor; + /* break; + } */ + if(!((i > main_width) && (row == m_zintSymbol->rows - 1))) { + painter.fillRect(i,y,linewidth,m_zintSymbol->row_height[row],QBrush(color)); + } else { + painter.fillRect(i,y + 8,linewidth,m_zintSymbol->row_height[row] - 3,QBrush(color)); + addon_text_height = y; + } + } + } + /* Add row binding */ + if(((m_zintSymbol->symbology == BARCODE_CODE16K) || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) { + painter.fillRect(0,y - 1,m_zintSymbol->width,2,QBrush(m_fgColor)); + } + if(((m_zintSymbol->symbology == BARCODE_CODABLOCKF) || (m_zintSymbol->symbology == BARCODE_HIBC_BLOCKF)) && (row != 0)) { + painter.fillRect(11,y - 1,m_zintSymbol->width - 24,2,QBrush(m_fgColor)); + } + y+=m_zintSymbol->row_height[row]; + } + } + + textdone = false; + + if(m_hidetext == false) { + painter.setFont(fontSmall); + if(((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) || + (m_zintSymbol->symbology == BARCODE_ISBNX)) { + /* Add bridge and format text for EAN */ + switch(caption.size()) { + case 8: + case 11: + case 14: + painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(32 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(34 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(64 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(66 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.setFont(fontLarge); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(0,4)); + painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(4,4)); + if(caption.size() == 11) { /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); }; + if(caption.size() == 14) { /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); }; + painter.setFont(fontSmall); + textdone = true; + break; + case 13: + case 16: + case 19: + painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(92 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(94 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.setFont(fontLarge); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9,Qt::AlignCenter, caption.mid(0,1)); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6)); + painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(7,6)); + if(caption.size() == 16) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(14,2)); }; + if(caption.size() == 19) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(14,5)); }; + painter.setFont(fontSmall); + textdone = true; + break; + } + if(textdone == false) { + painter.setFont(fontLarge); + painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9,Qt::AlignCenter, caption); + painter.setFont(fontSmall); + textdone = true; + } + } + + if((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { + /* Add bridge and format text for UPC-A */ + int block_width; + bool latch = true; + + j = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); + if(latch == true) { + /* a bar */ + painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor)); + latch = false; + } else { + /* a space */ + latch = true; + } + j += block_width; + } while (j < 11 + comp_offset); + painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + latch = true; + j = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); + if(latch == true) { + /* a bar */ + painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor)); + latch = false; + } else { + /* a space */ + latch = true; + } + j += block_width; + } while (j < 96 + comp_offset); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 7,Qt::AlignCenter, caption.mid(0,1)); + painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset, 7, 7,Qt::AlignCenter, caption.mid(11,1)); + painter.setFont(fontLarge); + painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(1,5)); + painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(6,5)); + if(caption.size() == 15) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(13,2)); }; + if(caption.size() == 18) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(13,5)); }; + painter.setFont(fontSmall); + textdone = true; + } + + if((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { + /* Add bridge and format text for UPC-E */ + painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.fillRect(50 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 7,Qt::AlignCenter, caption.mid(0,1)); + painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset, 7, 7,Qt::AlignCenter, caption.mid(7,1)); + painter.setFont(fontLarge); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6)); + if(caption.size() == 11) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); }; + if(caption.size() == 14) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); }; + painter.setFont(fontSmall); + textdone = true; + } + } /* if (m_hidetext == false) */ + + if((m_hidetext == false) && (textdone == false)) { + /* Add text to any other symbol */ + painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption); + } + painter.restore(); +} + +const QString & QZint::lastError() +{ + return m_lastError; +} + +bool QZint::hasErrors() +{ + return m_lastError.length(); +} + +} + diff --git a/backend_qt4/qzint.h b/backend_qt4/qzint.h new file mode 100644 index 00000000..7b6eaaa5 --- /dev/null +++ b/backend_qt4/qzint.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * * + * 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, see . * + ***************************************************************************/ + +#ifndef BARCODERENDER_H +#define BARCODERENDER_H +#include +#include + +#include "zint.h" + +namespace Zint +{ + +class QZint +{ +private: + +public: + enum BorderType{NO_BORDER=0, BIND=2, BOX=4}; + enum AspectRatioMode{IgnoreAspectRatio=0, KeepAspectRatio=1, CenterBarCode=2}; + +public: + QZint(); + ~QZint(); + + int symbol(); + void setSymbol(int symbol); + + QString text(); + void setText(const QString & text); + + QString primaryMessage(); + void setPrimaryMessage(const QString & primaryMessage); + + void setHeight(int height); + int height(); + + void setWidth(int width); + int width(); + + void setOption3(int option); + + QColor fgColor(); + void setFgColor(const QColor & fgColor); + + QColor bgColor(); + void setBgColor(const QColor & bgColor); + + BorderType borderType(); + void setBorderType(BorderType border); + + int borderWidth(); + void setBorderWidth(int boderWidth); + + int pdf417CodeWords(); + void setPdf417CodeWords(int pdf417CodeWords); + + int securityLevel(); + void setSecurityLevel(int securityLevel); + + float scale(); + void setScale(float scale); + + int mode(); + void setMode(int securityLevel); + + void setInputMode(int input_mode); + + void setWhitespace(int whitespace); + + QString error_message(); + + void render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode=IgnoreAspectRatio); + + const QString & lastError(); + bool hasErrors(); + + bool save_to_file(QString filename); + + void setHideText(bool hide); + +private: + void encode(); + int module_set(int y_coord, int x_coord); + +private: + int m_symbol; + QString m_text; + QString m_primaryMessage; + int m_height; + BorderType m_border; + int m_borderWidth; + int m_width; + int m_securityLevel; + int m_pdf417CodeWords; + int m_input_mode; + QColor m_fgColor; + QColor m_bgColor; + QString m_lastError; + int m_error; + int m_whitespace; + zint_symbol * m_zintSymbol; + float m_scale; + int m_option_3; + bool m_hidetext; +}; +} +#endif diff --git a/backend_qt4/readme b/backend_qt4/readme new file mode 100644 index 00000000..2ec3a7db --- /dev/null +++ b/backend_qt4/readme @@ -0,0 +1,9 @@ +Edit zint-1.6.pro and edit the 'DEFINES' section + NO_PNG -> compile zint without png support + NO_QR -> compile zint without QR support + QR_SYSTEM -> if you have QT installed in your system, zint will be compiled with QT support + QR -> compile zint with QR support static (you must have qrencode in the current folder) + +Edit compile_n_config and set the paths. + +Exec compile_n_config diff --git a/cmake/modules/FindQr.cmake b/cmake/modules/FindQr.cmake new file mode 100644 index 00000000..9bae7aa4 --- /dev/null +++ b/cmake/modules/FindQr.cmake @@ -0,0 +1,29 @@ +# - Find QRencode +# Find the native QRencode includes and library +# +# QR_INCLUDE_DIR - where to find qrencode.h, etc. +# QR_LIBRARIES - List of libraries when using QRencode. +# QR_FOUND - True if QRencode found. + + +IF (QR_INCLUDE_DIR) + # Already in cache, be silent + SET(QR_FIND_QUIETLY TRUE) +ENDIF (QR_INCLUDE_DIR) + +FIND_PATH(QR_INCLUDE_DIR qrencode.h) + +FIND_LIBRARY(QR_LIBRARY NAMES qrencode ) + +# handle the QUIETLY and REQUIRED arguments and set QR_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(QR DEFAULT_MSG QR_LIBRARY QR_INCLUDE_DIR) + +IF(QR_FOUND) + SET( QR_LIBRARIES ${QR_LIBRARY} ) +ELSE(QR_FOUND) + SET( QR_LIBRARIES ) +ENDIF(QR_FOUND) + +MARK_AS_ADVANCED( QR_LIBRARY QR_INCLUDE_DIR ) diff --git a/cmake/modules/FindZint.cmake b/cmake/modules/FindZint.cmake new file mode 100644 index 00000000..7b4f6b5f --- /dev/null +++ b/cmake/modules/FindZint.cmake @@ -0,0 +1,58 @@ +# - Find Zint and QZint +# Find the native Zint and QZint includes and library +# +# ZINT_INCLUDE_DIR - where to find zint.h, etc. +# ZINT_LIBRARIES - List of libraries when using zint. +# ZINT_FOUND - True if zint found. +# QZINT_INCLUDE_DIR - where to find qzint.h, etc. +# QZINT_LIBRARIES - List of libraries when using qzint. +# QZINT_FOUND - True if qzint found. + +################### FIND ZINT ###################### + +IF (ZINT_INCLUDE_DIR) + # Already in cache, be silent + SET(ZINT_FIND_QUIETLY TRUE) +ENDIF (ZINT_INCLUDE_DIR) + +FIND_PATH(ZINT_INCLUDE_DIR zint.h) + +FIND_LIBRARY(ZINT_LIBRARY NAMES zint ) + +# handle the QUIETLY and REQUIRED arguments and set ZINT_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Zint DEFAULT_MSG ZINT_LIBRARY ZINT_INCLUDE_DIR) + +IF(ZINT_FOUND) + SET( ZINT_LIBRARIES ${ZINT_LIBRARY} ) +ELSE(ZINT_FOUND) + SET( ZINT_LIBRARIES ) +ENDIF(ZINT_FOUND) + +MARK_AS_ADVANCED( ZINT_LIBRARY ZINT_INCLUDE_DIR ) + +################### FIND QZINT ###################### + +IF (QZINT_INCLUDE_DIR) + # Already in cache, be silent + SET(QZINT_FIND_QUIETLY TRUE) +ENDIF (QZINT_INCLUDE_DIR) + +FIND_PATH(QZINT_INCLUDE_DIR qzint.h) + +FIND_LIBRARY(QZINT_LIBRARY NAMES QZint ) + +# handle the QUIETLY and REQUIRED arguments and set QZINT_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(QZint DEFAULT_MSG QZINT_LIBRARY QZINT_INCLUDE_DIR) + +IF(QZINT_FOUND) + SET( QZINT_LIBRARIES ${QZINT_LIBRARY} ) +ELSE(QZINT_FOUND) + SET( QZINT_LIBRARIES ) +ENDIF(QZINT_FOUND) + +MARK_AS_ADVANCED( QZINT_LIBRARY QZINT_INCLUDE_DIR ) + diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 00000000..87e6b062 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") +# IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) +# ELSE(EXISTS "$ENV{DESTDIR}${file}") +# MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") +# ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000..23d06f5d --- /dev/null +++ b/debian/changelog @@ -0,0 +1,44 @@ +zint (2.2.1-1) unstable; urgency=low + + * fix .so version + + -- BogDan Vatra Sat, 08 Aug 2009 11:52:28 +0300 + +zint (2.2.1) unstable; urgency=low + + * bug fixes. Affected symbologies are Data Matrix, + USPS One Code, Aztec Code, PDF417, MicroPDF and Composite symbols. + If you use any of these then please update. + + -- BogDan Vatra Fri, 07 Aug 2009 15:04:12 +0300 + +zint (2.2.0-1) unstable; urgency=low + + * Debian testing/sid and (*)ubuntu debug packages + + -- BogDan Vatra Thu, 06 Aug 2009 21:57:37 +0300 + +zint (2.2.0) unstable; urgency=low + + * Code One encoding + * Another round of bugfixes + * GS-1 data can now be encoded in Code 49 symbols + * The Qt GUI has been renamed to "zint-qt" and now includes a handy + reset button. + + -- BogDan Vatra Tue, 04 Aug 2009 18:44:39 +0300 + +zint (2.1.3-1) unstable; urgency=low + + * Much improved GUI experience - now with a "save" button so that the GUI + actually does something! + * Also included are, of course, Code 49, Channel Code, Japanese Postal Code. + * A shed load of bugfixes. + + -- BogDan Vatra Wed, 20 May 2009 10:51:18 +0300 + +zint (2.1.3) unstable; urgency=low + + * Initial release + + -- BogDan Vatra Sat, 11 Apr 2009 23:45:53 +0300 diff --git a/debian/compat b/debian/compat new file mode 100644 index 00000000..7f8f011e --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..30b9701e --- /dev/null +++ b/debian/control @@ -0,0 +1,64 @@ +Source: zint +Section: libs +Priority: extra +Maintainer: BogDan Vatra +Build-Depends: cdbs, debhelper (>= 7), cmake, libpng12-dev, libqrencode-dev, libqt4-dev +Standards-Version: 3.8.1 +Homepage: http://www.zint.org.uk/ + +Package: libzint +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Zint is an Open Source barcode encoding and image generating library for Linux. + It currently features: + Over 50 symbologies including many not available in any other open source package. + Unicode translation for symbologies which support Latin-1 and Shift-JIS character sets. + Full GS1 support including data verification and automated insertion of FNC1 characters. + Support for encoding binary data including NULL (ASCII 0) characters. + Health Industry Barcode (HIBC) encoding capabilities. + +Package: libzint-dbg +Section: libs +Architecture: any +Priority: extra +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Debugging symbols for Zint library. + This package contains debugging files used to investigate problems with + Zint binaries and libraries. + +Package: libzint-dev +Section: libdevel +Architecture: any +Depends: libzint (= ${binary:Version}) +Description: Zint development files. + This package contains development files for zint. + +Package: libqzint +Section: libs +Architecture: any +Depends: libzint (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Description: Qt wrapper over Zint library + This package contains Qt wrapper over Zint library. + +Package: libqzint-dev +Section: libdevel +Architecture: any +Depends: libqzint (= ${binary:Version}), libzint-dev (= ${source:Version}) +Description: QZint development files. + This package contains development files for the Qt wrapper over Zint library.. + +Package: zintfrontend +Section: libs +Architecture: any +Depends: libzint (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Description: Zint console frontend. + This package contains a console frontend. + +Package: qzintfrontend +Section: libs +Architecture: any +Depends: libzint (= ${binary:Version}), libqzint (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Description: Zint QT frontend. + This package contains an easy to use QT frontend. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 00000000..23fd34c4 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,39 @@ +This package was debianized by: + + BogDan Vatra on Sat, 11 Apr 2009 23:45:53 +0300 + +It was downloaded from: + + + +Upstream Author(s): + + Robin Stuart + +Copyright: + + + +License: + + 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 package 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, see . + +On Debian systems, the complete text of the GNU General +Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'. + +The Debian packaging is: + + Copyright (C) 2009 BogDan Vatra + +and is licensed under the GPL version 3, see above. diff --git a/debian/libqzint-dev.install b/debian/libqzint-dev.install new file mode 100644 index 00000000..63169a18 --- /dev/null +++ b/debian/libqzint-dev.install @@ -0,0 +1,2 @@ +usr/include/qzint.h +usr/lib/libQZint.so diff --git a/debian/libqzint.install b/debian/libqzint.install new file mode 100644 index 00000000..d07ebfb1 --- /dev/null +++ b/debian/libqzint.install @@ -0,0 +1 @@ +usr/lib/libQZint.so.* diff --git a/debian/libzint-dev.install b/debian/libzint-dev.install new file mode 100644 index 00000000..b9ec78ba --- /dev/null +++ b/debian/libzint-dev.install @@ -0,0 +1,3 @@ +usr/include/zint.h +usr/lib/libzint.so +usr/share/cmake-2.6/Modules/FindZint.cmake diff --git a/debian/libzint.install b/debian/libzint.install new file mode 100644 index 00000000..f363cca8 --- /dev/null +++ b/debian/libzint.install @@ -0,0 +1 @@ +usr/lib/libzint.so.* diff --git a/debian/qzintfrontend.install b/debian/qzintfrontend.install new file mode 100644 index 00000000..66674579 --- /dev/null +++ b/debian/qzintfrontend.install @@ -0,0 +1 @@ +usr/bin/zint-qt diff --git a/debian/rules b/debian/rules new file mode 100755 index 00000000..fbb8b66e --- /dev/null +++ b/debian/rules @@ -0,0 +1,9 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/cmake.mk + +DEB_DBG_PACKAGE_libzint := libzint-dbg +DEB_DBG_PACKAGE_libqzint := libzint-dbg +DEB_DBG_PACKAGE_zintfrontend := libzint-dbg +DEB_DBG_PACKAGE_qzintfrontend := libzint-dbg diff --git a/debian/zintfrontend.install b/debian/zintfrontend.install new file mode 100644 index 00000000..294ee99a --- /dev/null +++ b/debian/zintfrontend.install @@ -0,0 +1 @@ +usr/bin/zint diff --git a/docs/README b/docs/README new file mode 100644 index 00000000..2c3d1769 --- /dev/null +++ b/docs/README @@ -0,0 +1,3 @@ +Documentation has now been removed from the Zint package in +preference of the online documentation at: +http://www.zint.org.uk \ No newline at end of file diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt new file mode 100644 index 00000000..05db17d2 --- /dev/null +++ b/frontend/CMakeLists.txt @@ -0,0 +1,19 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(zint_frontend) + +set(zint_frontend_SRCS main.c ) + +include_directories(BEFORE "${CMAKE_SOURCE_DIR}/backend") + +add_executable(zint_frontend ${zint_frontend_SRCS}) + +set_target_properties(zint_frontend PROPERTIES OUTPUT_NAME "zint") + +add_dependencies(zint_frontend zint) + +link_directories( "${CMAKE_BINARY_DIR}/backend" ) + +target_link_libraries(zint_frontend zint) + +install(TARGETS zint_frontend DESTINATION "${BIN_INSTALL_DIR}" RUNTIME) diff --git a/frontend/Makefile b/frontend/Makefile new file mode 100644 index 00000000..31c293bc --- /dev/null +++ b/frontend/Makefile @@ -0,0 +1,31 @@ +# Linux makefile for zint - requires libzint +# +# make compiles zint +# make install copies binary to /usr/local/bin +# make uninstall removes the binary +# make clean cleans up a previous compilation and any object or editor files +# + +ZINT_VERSION:=-DZINT_VERSION=\"2.3.2\" + +CC := gcc +INCLUDE := -I/usr/include +CFLAGS := -g + +prefix := /usr +bindir := $(prefix)/bin +DESTDIR := + +zint: main.c + $(CC) -Wall $(INCLUDE) $(CFLAGS) $(ZINT_VERSION) -I../backend -L../backend main.c -o zint -lzint + +.PHONY: install uninstall clean dist + +clean: + rm -f zint *.o *.a *~ *.png *.eps *.svg *.log + +install: + install -D -p zint $(DESTDIR)$(bindir)/zint + +uninstall: + rm $(DESTDIR)$(bindir)/zint diff --git a/frontend/Makefile.mingw b/frontend/Makefile.mingw new file mode 100644 index 00000000..859ac02e --- /dev/null +++ b/frontend/Makefile.mingw @@ -0,0 +1,37 @@ +# Linux makefile for zint - requires libzint +# +# make compiles zint +# make install copies binary to /usr/bin +# make uninstall removes the binary +# make clean cleans up a previous compilation and any object or editor files +# + +ZINT_VERSION:=-DZINT_VERSION=\"2.3.2\" + +CC := gcc +CFLAGS := -D_WIN32 -O2 -fms-extensions -mms-bitfields -fno-exceptions -fomit-frame-pointer -Wall -I../backend +prefix := /mingw +bindir := $(prefix)/bin +DESTDIR := + +all: zint zint_static + +%.res:%.rc + windres -O coff --input-format=rc -i $< -o $@ + +zint: main.c zint.res + $(CC) $(CFLAGS) -DZINT_DLL -DPNG_DLL -DZLIB_DLL $(ZINT_VERSION) $? zint.res -o $@ -L../backend -lzint + +zint_static: main.c zint.res + $(CC) -static $(CFLAGS) $(ZINT_VERSION) $? zint.res -o $@ -L../backend -lzint -lpng -lz + +.PHONY: install uninstall clean dist + +clean: + rm -f zint *.o *.a *~ *.png *.eps *.svg *.log *.exe *.bak *.res + +install: + install -D -p zint $(DESTDIR)$(bindir)/zint + +uninstall: + rm $(DESTDIR)$(bindir)/zint diff --git a/frontend/getopt.c b/frontend/getopt.c new file mode 100644 index 00000000..b270074b --- /dev/null +++ b/frontend/getopt.c @@ -0,0 +1,1213 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + This file is part of the GNU C Library. + + 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 2, 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. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#include + +#ifdef VMS +# include +#endif + +#ifdef USEGETTEXT +#ifdef _LIBC +# include +#else +/* This is for other GNU distributions with internationalized messages. */ +# include "gettext.h" +#endif +#define _(msgid) gettext (msgid) +#else +#define _(msgid) (msgid) +#endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized attribute_hidden; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifndef __GNU_LIBRARY__ + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (char **argv) +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (int argc, char *const *argv, const char *optstring) +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == __libc_argc && argv == __libc_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (int argc, char *const *argv, + const char *optstring, const struct option *longopts, + int *longind, int long_only) +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only + && (argv[optind][2] || !strchr (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]) >= 0) + { + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (argv[optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || strchr (optstring, *nextchar) == NULL) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (argv[optind][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = strchr (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/frontend/getopt.h b/frontend/getopt.h new file mode 100644 index 00000000..cc45f46f --- /dev/null +++ b/frontend/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + + Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, + 1999, 2001, 2003 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + 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 2, 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. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* __GNU_LIBRARY__ */ + +#ifndef __need_getopt +extern int getopt_long (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +#endif + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/frontend/getopt1.c b/frontend/getopt1.c new file mode 100644 index 00000000..e3624625 --- /dev/null +++ b/frontend/getopt1.c @@ -0,0 +1,185 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, + 1997, 1998, 2003 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + 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 2, 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. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef _LIBC +# include +#else +# include "getopt.h" +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (int argc, + char *const *argv, + const char *options, + const struct option *long_options, + int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (int argc, + char *const *argv, + const char *options, + const struct option *long_options, + int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + +# ifdef _LIBC +libc_hidden_def (getopt_long) +libc_hidden_def (getopt_long_only) +# endif + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/frontend/main.c b/frontend/main.c new file mode 100644 index 00000000..726e04a7 --- /dev/null +++ b/frontend/main.c @@ -0,0 +1,391 @@ +/* main.c - Command line handling routines for Zint */ + +/* + libzint - the open source barcode library + Copyright (C) 2008 Robin Stuart + + 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 +#include +#include +#ifndef _MSC_VER +#include +#include +#else +#include "getopt.h" +#include "zint.h" +#endif +#define NESET "0123456789" + +void types(void) { + printf( " 1: Code 11 51: Pharma One-Track 90: KIX Code\n" + " 2: Standard 2of5 52: PZN 92: Aztec Code\n" + " 3: Interleaved 2of5 53: Pharma Two-Track 93: DAFT Code\n" + " 4: IATA 2of5 55: PDF417 97: Micro QR Code\n" + " 6: Data Logic 56: PDF417 Trunc 98: HIBC Code 128\n" + " 7: Industrial 2of5 57: Maxicode 99: HIBC Code 39\n" + " 8: Code 39 58: QR Code 102: HIBC Data Matrix\n" + " 9: Extended Code 39 60: Code 128-B 104: HIBC QR Code\n" + "13: EAN 63: AP Standard Customer 106: HIBC PDF417\n" + "16: GS1-128 66: AP Reply Paid 108: HIBC MicroPDF417\n" + "18: Codabar 67: AP Routing 112: HIBC Aztec Code\n" + "20: Code 128 68: AP Redirection 128: Aztec Runes\n" + "21: Leitcode 69: ISBN 129: Code 23\n" + "22: Identcode 70: RM4SCC 130: Comp EAN\n" + "23: Code 16k 71: Data Matrix 131: Comp GS1-128\n" + "24: Code 49 72: EAN-14 132: Comp Databar-14\n" + "25: Code 93 75: NVE-18 133: Comp Databar Ltd\n" + "28: Flattermarken 76: Japanese Post 134: Comp Databar Ext\n" + "29: Databar-14 77: Korea Post 135: Comp UPC-A\n" + "30: Databar Limited 79: Databar-14 Stack 136: Comp UPC-E\n" + "31: Databar Extended 80: Databar-14 Stack Omni 137: Comp Databar-14 Stack\n" + "32: Telepen Alpha 81: Databar Extended Stack 138: Comp Databar Stack Omni\n" + "34: UPC-A 82: Planet 139: Comp Databar Ext Stack\n" + "37: UPC-E 84: MicroPDF 140: Channel Code\n" + "40: Postnet 85: USPS OneCode 141: Code One\n" + "47: MSI Plessey 86: UK Plessey 142: Grid Matrix\n" + "49: FIM 87: Telepen Numeric\n" + "50: Logmars 89: ITF-14\n" + ); +} + +void usage(void) +{ + printf( + "Zint version %s\n" + "Encode input data in a barcode and save as a PNG, EPS or SVG file.\n\n" + " -h, --help Display this message.\n" + " -t, --types Display table of barcode types\n" + " -i, --input=FILE Read data from FILE.\n" + " -o, --output=FILE Write image to FILE. (default is out.png)\n" + " -d, --data=DATA Barcode content.\n" + " -b, --barcode=NUMBER Number of barcode type (default is 20 (=Code128)).\n" + " --height=NUMBER Height of symbol in multiples of x-dimension.\n" + " -w, --whitesp=NUMBER Width of whitespace in multiples of x-dimension.\n" + " --border=NUMBER Width of border in multiples of x-dimension.\n" + " --box Add a box.\n" + " --bind Add boundary bars.\n" + " -r, --reverse Reverse colours (white on black).\n" + " --fg=COLOUR Specify a foreground colour.\n" + " --bg=COLOUR Specify a background colour.\n" + " --scale=NUMBER Adjust size of output image.\n" + " --directpng Send PNG output to stdout\n" + " --directeps Send EPS output to stdout\n" + " --directsvg Send SVG output to stdout\n" + " --rotate=NUMBER Rotate symbol (PNG output only).\n" + " --cols=NUMBER (PDF417) Number of columns.\n" + " --vers=NUMBER (QR Code) Version\n" + " --secure=NUMBER (PDF417 and QR Code) Error correction level.\n" + " --primary=STRING (Maxicode and Composite) Structured primary message.\n" + " --mode=NUMBER (Maxicode and Composite) Set encoding mode.\n" + " --gs1 Treat input as GS1 data\n" + " --binary Treat input as Binary data\n" + " --notext Remove human readable text\n" + " --square Force Data Matrix symbols to be square\n" + , ZINT_VERSION); +} + +int validator(char test_string[], char source[]) +{ /* Verifies that a string only uses valid characters */ + unsigned int i, j, latch; + + for(i = 0; i < strlen(source); i++) { + latch = 0; + for(j = 0; j < strlen(test_string); j++) { + if (source[i] == test_string[j]) { latch = 1; } } + if (!(latch)) { + return ERROR_INVALID_DATA; } + } + + return 0; +} + +int main(int argc, char **argv) +{ + struct zint_symbol *my_symbol; + int c; + int error_number; + int rotate_angle; + int generated; + + error_number = 0; + rotate_angle = 0; + generated = 0; + my_symbol = ZBarcode_Create(); + my_symbol->input_mode = UNICODE_MODE; + + 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'}, + {"bind", 0, 0, 0}, + {"box", 0, 0, 0}, + {"directeps", 0, 0, 0}, + {"directpng", 0, 0, 0}, + {"directsvg", 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}, + {"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}, + {"kanji", 0, 0, 0}, + {"sjis", 0, 0, 0}, + {"binary", 0, 0, 0}, + {"notext", 0, 0, 0}, + {"square", 0, 0, 0}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "htb:w:d:o:i:rcmp", 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, "directeps")) { + my_symbol->output_options += BARCODE_STDOUT; + strncpy(my_symbol->outfile, "dummy.eps", 10); + } + if(!strcmp(long_options[option_index].name, "directpng")) { + my_symbol->output_options += BARCODE_STDOUT; + strncpy(my_symbol->outfile, "dummy.png", 10); + } + if(!strcmp(long_options[option_index].name, "directsvg")) { + my_symbol->output_options += BARCODE_STDOUT; + strncpy(my_symbol->outfile, "dummy.svg", 10); + } + if(!strcmp(long_options[option_index].name, "gs1")) { + my_symbol->input_mode = GS1_MODE; + } + if(!strcmp(long_options[option_index].name, "kanji")) { + my_symbol->input_mode = KANJI_MODE; + } + if(!strcmp(long_options[option_index].name, "sjis")) { + my_symbol->input_mode = SJIS_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; + } + 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, "Invalid scale value\n"); + my_symbol->scale = 1.0; + } + } + if(!strcmp(long_options[option_index].name, "border")) { + error_number = validator(NESET, optarg); + if(error_number == ERROR_INVALID_DATA) { + fprintf(stderr, "Invalid border width\n"); + exit(1); + } + if((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) { + my_symbol->border_width = atoi(optarg); + } else { + fprintf(stderr, "Border width out of range\n"); + } + } + if(!strcmp(long_options[option_index].name, "height")) { + error_number = validator(NESET, optarg); + if(error_number == ERROR_INVALID_DATA) { + fprintf(stderr, "Invalid symbol height\n"); + exit(1); + } + if((atoi(optarg) >= 1) && (atoi(optarg) <= 1000)) { + my_symbol->height = atoi(optarg); + } else { + fprintf(stderr, "Symbol height out of range\n"); + } + } + + if(!strcmp(long_options[option_index].name, "cols")) { + if((atoi(optarg) >= 1) && (atoi(optarg) <= 30)) { + my_symbol->option_2 = atoi(optarg); + } else { + fprintf(stderr, "Number of columns out of range\n"); + } + } + if(!strcmp(long_options[option_index].name, "vers")) { + if((atoi(optarg) >= 1) && (atoi(optarg) <= 40)) { + my_symbol->option_2 = atoi(optarg); + } else { + fprintf(stderr, "Invalid QR Code version\n"); + } + } + if(!strcmp(long_options[option_index].name, "secure")) { + if((atoi(optarg) >= 1) && (atoi(optarg) <= 8)) { + my_symbol->option_1 = atoi(optarg); + } else { + fprintf(stderr, "ECC level out of range\n"); + } + } + if(!strcmp(long_options[option_index].name, "primary")) { + if(strlen(optarg) <= 90) { + strcpy(my_symbol->primary, optarg); + } else { + fprintf(stderr, "Primary data string too long"); + } + } + if(!strcmp(long_options[option_index].name, "mode")) { + /* Don't allow specification of modes 2 and 3 - do it + automagically instead */ + if((optarg[0] >= '0') && (optarg[0] <= '6')) { + my_symbol->option_1 = optarg[0] - '0'; + } else { + fprintf(stderr, "Invalid mode\n"); + } + } + if(!strcmp(long_options[option_index].name, "rotate")) { + /* Only certain inputs allowed */ + error_number = validator(NESET, optarg); + if(error_number == ERROR_INVALID_DATA) { + fprintf(stderr, "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; + } + } + break; + + case 'h': + usage(); + break; + + case 't': + types(); + break; + + case 'b': + error_number = validator(NESET, optarg); + if(error_number == ERROR_INVALID_DATA) { + fprintf(stderr, "Invalid barcode type\n"); + exit(1); + } + my_symbol->symbology = atoi(optarg); + break; + + case 'w': + error_number = validator(NESET, optarg); + if(error_number == ERROR_INVALID_DATA) { + fprintf(stderr, "Invalid whitespace value\n"); + exit(1); + } + if((atoi(optarg) >= 0) && (atoi(optarg) <= 1000)) { + my_symbol->whitespace_width = atoi(optarg); + } else { + fprintf(stderr, "Whitespace value out of range"); + } + break; + + case 'd': /* we have some data! */ + error_number = ZBarcode_Encode(my_symbol, (unsigned char*)optarg, strlen(optarg)); + if(error_number == 0) { + error_number = ZBarcode_Print(my_symbol, rotate_angle); + } + generated = 1; + if(error_number != 0) { + fprintf(stderr, "%s\n", my_symbol->errtxt); + ZBarcode_Delete(my_symbol); + return 1; + } + break; + + case 'i': /* Take data from file */ + error_number = ZBarcode_Encode_File(my_symbol, optarg); + if(error_number == 0) { + error_number = ZBarcode_Print(my_symbol, rotate_angle); + } + generated = 1; + if(error_number != 0) { + fprintf(stderr, "%s\n", my_symbol->errtxt); + 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, "?? getopt error 0%o\n", c); + } + } + + if (optind < argc) { + fprintf(stderr, "Invalid option "); + while (optind < argc) + fprintf(stderr, "%s", argv[optind++]); + fprintf(stderr, "\n"); + } + + if(generated == 0) { + fprintf(stderr, "error: No data received, no symbol generated\n"); + } + + ZBarcode_Delete(my_symbol); + + return error_number; +} diff --git a/frontend/test.sh b/frontend/test.sh new file mode 100755 index 00000000..1ba06469 --- /dev/null +++ b/frontend/test.sh @@ -0,0 +1,423 @@ +echo testing Code 11 +zint -o bar01.png -b 1 --height=50 --border=10 -d 87654321 +zint -o bar01.eps -b 1 --height=50 --border=10 -d 87654321 +zint -o bar01.svg -b 1 --height=50 --border=10 -d 87654321 +echo testing Code 2 of 5 Standard +zint -o bar02.png -b 2 --height=50 --border=10 -d 87654321 +zint -o bar02.eps -b 2 --height=50 --border=10 -d 87654321 +zint -o bar02.svg -b 2 --height=50 --border=10 -d 87654321 +echo testing Interleaved 2 of 5 +zint -o bar03.png -b 3 --height=50 --border=10 -d 87654321 +zint -o bar03.eps -b 3 --height=50 --border=10 -d 87654321 +zint -o bar03.svg -b 3 --height=50 --border=10 -d 87654321 +echo testing Code 2 of 5 IATA +zint -o bar04.png -b 4 --height=50 --border=10 -d 87654321 +zint -o bar04.eps -b 4 --height=50 --border=10 -d 87654321 +zint -o bar04.svg -b 4 --height=50 --border=10 -d 87654321 +echo testing Code 2 of 5 Data Logic +zint -o bar06.png -b 6 --height=50 --border=10 -d 87654321 +zint -o bar06.eps -b 6 --height=50 --border=10 -d 87654321 +zint -o bar06.svg -b 6 --height=50 --border=10 -d 87654321 +echo testing Code 2 of 5 Industrial +zint -o bar07.png -b 7 --height=50 --border=10 -d 87654321 +zint -o bar07.eps -b 7 --height=50 --border=10 -d 87654321 +zint -o bar07.svg -b 7 --height=50 --border=10 -d 87654321 +echo testing Code 39 +zint -o bar08.png -b 8 --height=50 --border=10 -d CODE39 +zint -o bar08.eps -b 8 --height=50 --border=10 -d CODE39 +zint -o bar08.svg -b 8 --height=50 --border=10 -d CODE39 +echo testing Extended Code 39 +zint -o bar09.png -b 9 --height=50 --border=10 -d 'Code 39e' +zint -o bar09.eps -b 9 --height=50 --border=10 -d 'Code 39e' +zint -o bar09.svg -b 9 --height=50 --border=10 -d 'Code 39e' +echo testing EAN8 +zint -o bar10.png -b 13 --height=50 --border=10 -d 7654321 +zint -o bar10.eps -b 13 --height=50 --border=10 -d 7654321 +zint -o bar10.svg -b 13 --height=50 --border=10 -d 7654321 +echo testing EAN8 - 2 digits add on +zint -o bar11.png -b 13 --height=50 --border=10 -d 7654321+21 +zint -o bar11.eps -b 13 --height=50 --border=10 -d 7654321+21 +zint -o bar11.svg -b 13 --height=50 --border=10 -d 7654321+21 +echo testing EAN8 - 5 digits add-on +zint -o bar12.png -b 13 --height=50 --border=10 -d 7654321+54321 +zint -o bar12.eps -b 13 --height=50 --border=10 -d 7654321+54321 +zint -o bar12.svg -b 13 --height=50 --border=10 -d 7654321+54321 +echo testing EAN13 +zint -o bar13.png -b 13 --height=50 --border=10 -d 210987654321 +zint -o bar13.eps -b 13 --height=50 --border=10 -d 210987654321 +zint -o bar13.svg -b 13 --height=50 --border=10 -d 210987654321 +echo testing EAN13 - 2 digits add-on +zint -o bar14.png -b 13 --height=50 --border=10 -d 210987654321+21 +zint -o bar14.eps -b 13 --height=50 --border=10 -d 210987654321+21 +zint -o bar14.svg -b 13 --height=50 --border=10 -d 210987654321+21 +echo testing EAN13 - 5 digits add-on +zint -o bar15.png -b 13 --height=50 --border=10 -d 210987654321+54321 +zint -o bar15.eps -b 13 --height=50 --border=10 -d 210987654321+54321 +zint -o bar15.svg -b 13 --height=50 --border=10 -d 210987654321+54321 +echo testing GS1-128 +zint -o bar16.png -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +zint -o bar16.eps -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +zint -o bar16.svg -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +echo testing CodaBar +zint -o bar18.png -b 18 --height=50 --border=10 -d D765432C +zint -o bar18.eps -b 18 --height=50 --border=10 -d D765432C +zint -o bar18.svg -b 18 --height=50 --border=10 -d D765432C +echo testing Code 128 +zint -o bar20.png -b 20 --height=50 --border=10 -d 'Code 128' +zint -o bar20.eps -b 20 --height=50 --border=10 -d 'Code 128' +zint -o bar20.svg -b 20 --height=50 --border=10 -d 'Code 128' +echo testing Deutsche Post Leitcode +zint -o bar21.png -b 21 --height=50 --border=10 -d 3210987654321 +zint -o bar21.eps -b 21 --height=50 --border=10 -d 3210987654321 +zint -o bar21.svg -b 21 --height=50 --border=10 -d 3210987654321 +echo testing Deutsche Post Identcode +zint -o bar22.png -b 22 --height=50 --border=10 -d 10987654321 +zint -o bar22.eps -b 22 --height=50 --border=10 -d 10987654321 +zint -o bar22.svg -b 22 --height=50 --border=10 -d 10987654321 +echo testing Code 16k +zint -o bar23.png -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" +zint -o bar23.eps -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" +zint -o bar23.svg -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" +zint -o bar23a.png -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar23a.eps -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar23a.svg -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +echo testing Code 49 +zint -o bar24.png -b 24 -d "Demonstration Code 49" +zint -o bar24.eps -b 24 -d "Demonstration Code 49" +zint -o bar24.svg -b 24 -d "Demonstration Code 49" +echo testing Code 93 +zint -o bar25.png -b 25 --height=50 --border=10 -d 'Code 93' +zint -o bar25.eps -b 25 --height=50 --border=10 -d 'Code 93' +zint -o bar25.svg -b 25 --height=50 --border=10 -d 'Code 93' +echo testing Flattermarken +zint -o bar28.png -b 28 --height=50 --border=10 -d 87654321 +zint -o bar28.eps -b 28 --height=50 --border=10 -d 87654321 +zint -o bar28.svg -b 28 --height=50 --border=10 -d 87654321 +echo testing DataBar-14 +zint -o bar29.png -b 29 --height=33 --border=10 -d 2001234567890 +zint -o bar29.eps -b 29 --height=33 --border=10 -d 2001234567890 +zint -o bar29.svg -b 29 --height=33 --border=10 -d 2001234567890 +echo testing DataBar Limited +zint -o bar30.png -b 30 --height=50 --border=10 -w 2 -d 31234567890 +zint -o bar30.eps -b 30 --height=50 --border=10 -w 2 -d 31234567890 +zint -o bar30.svg -b 30 --height=50 --border=10 -w 2 -d 31234567890 +echo testing DataBar Expanded +zint -o bar31.png -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" +zint -o bar31.eps -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" +zint -o bar31.svg -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" +echo testing Telepen Alpha +zint -o bar32.png -b 32 --height=50 --border=10 -d 'Telepen' +zint -o bar32.eps -b 32 --height=50 --border=10 -d 'Telepen' +zint -o bar32.svg -b 32 --height=50 --border=10 -d 'Telepen' +echo testing UPC A +zint -o bar34.png -b 34 --height=50 --border=10 -d 10987654321 +zint -o bar34.eps -b 34 --height=50 --border=10 -d 10987654321 +zint -o bar34.svg -b 34 --height=50 --border=10 -d 10987654321 +echo testing UPC A - 2 digit add-on +zint -o bar35.png -b 34 --height=50 --border=10 -d 10987654321+21 +zint -o bar35.eps -b 34 --height=50 --border=10 -d 10987654321+21 +zint -o bar35.svg -b 34 --height=50 --border=10 -d 10987654321+21 +echo testing UPC A - 5 digit add-on +zint -o bar36.png -b 36 --height=50 --border=10 -d 10987654321+54321 +zint -o bar36.eps -b 36 --height=50 --border=10 -d 10987654321+54321 +zint -o bar36.svg -b 36 --height=50 --border=10 -d 10987654321+54321 +echo testing UPC E +zint -o bar37.png -b 37 --height=50 --border=10 -d 654321 +zint -o bar37.eps -b 37 --height=50 --border=10 -d 654321 +zint -o bar37.svg -b 37 --height=50 --border=10 -d 654321 +echo testing UPC E - 2 digit add-on +zint -o bar38.png -b 37 --height=50 --border=10 -d 654321+21 +zint -o bar38.eps -b 37 --height=50 --border=10 -d 654321+21 +zint -o bar38.svg -b 37 --height=50 --border=10 -d 654321+21 +echo testing UPC E - 5 digit add-on +zint -o bar39.png -b 37 --height=50 --border=10 -d 654321+54321 +zint -o bar39.eps -b 37 --height=50 --border=10 -d 654321+54321 +zint -o bar39.svg -b 37 --height=50 --border=10 -d 654321+54321 +echo testing PostNet-6 +zint -o bar41.png -b 40 --border=10 -d 54321 +zint -o bar41.eps -b 40 --border=10 -d 54321 +zint -o bar41.svg -b 40 --border=10 -d 54321 +echo testing PostNet-10 +zint -o bar43.png -b 40 --border=10 -d 987654321 +zint -o bar43.eps -b 40 --border=10 -d 987654321 +zint -o bar43.svg -b 40 --border=10 -d 987654321 +echo testing PostNet-12 +zint -o bar45.png -b 40 --border=10 -d 10987654321 +zint -o bar45.eps -b 40 --border=10 -d 10987654321 +zint -o bar45.svg -b 40 --border=10 -d 10987654321 +echo testing MSI Code +zint -o bar47.png -b 47 --height=50 --border=10 -d 87654321 +zint -o bar47.eps -b 47 --height=50 --border=10 -d 87654321 +zint -o bar47.svg -b 47 --height=50 --border=10 -d 87654321 +echo testing FIM +zint -o bar49.png -b 49 --height=50 --border=10 -d D +zint -o bar49.eps -b 49 --height=50 --border=10 -d D +zint -o bar49.svg -b 49 --height=50 --border=10 -d D +echo testing LOGMARS +zint -o bar50.png -b 50 --height=50 --border=10 -d LOGMARS +zint -o bar50.eps -b 50 --height=50 --border=10 -d LOGMARS +zint -o bar50.svg -b 50 --height=50 --border=10 -d LOGMARS +echo testing Pharmacode One-Track +zint -o bar51.png -b 51 --height=50 --border=10 -d 123456 +zint -o bar51.eps -b 51 --height=50 --border=10 -d 123456 +zint -o bar51.svg -b 51 --height=50 --border=10 -d 123456 +echo testing Pharmazentralnumber +zint -o bar52.png -b 52 --height=50 --border=10 -d 654321 +zint -o bar52.eps -b 52 --height=50 --border=10 -d 654321 +zint -o bar52.svg -b 52 --height=50 --border=10 -d 654321 +echo testing Pharmacode Two-Track +zint -o bar53.png -b 53 --height=50 --border=10 -d 12345678 +zint -o bar53.eps -b 53 --height=50 --border=10 -d 12345678 +zint -o bar53.svg -b 53 --height=50 --border=10 -d 12345678 +echo testing PDF417 +zint -o bar55.png -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +zint -o bar55.eps -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +zint -o bar55.svg -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +echo testing PDF417 Truncated +zint -o bar56.png -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +zint -o bar56.eps -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +zint -o bar56.svg -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" +echo testing Maxicode +zint -o bar57.png -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" +zint -o bar57.eps -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" +zint -o bar57.svg -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" +echo testing QR Code +zint -o bar58.png -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" +zint -o bar58.eps -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" +zint -o bar58.svg -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" +zint -o bar58k.png -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" +zint -o bar58k.eps -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" +zint -o bar58k.svg -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" +echo testing Code 128 Subset B +zint -o bar60.png -b 60 --height=50 --border=10 -d 87654321 +zint -o bar60.eps -b 60 --height=50 --border=10 -d 87654321 +zint -o bar60.svg -b 60 --height=50 --border=10 -d 87654321 +echo testing Australian Post Standard Customer +zint -o bar63.png -b 63 --border=10 -d 87654321 +zint -o bar63.eps -b 63 --border=10 -d 87654321 +zint -o bar63.svg -b 63 --border=10 -d 87654321 +echo testing Australian Post Customer 2 +zint -o bar64.png -b 63 --border=10 -d 87654321AUSPS +zint -o bar64.eps -b 63 --border=10 -d 87654321AUSPS +zint -o bar64.svg -b 63 --border=10 -d 87654321AUSPS +echo testing Australian Post Customer 3 +zint -o bar65.png -b 63 --border=10 -d '87654321 AUSTRALIA' +zint -o bar65.eps -b 63 --border=10 -d '87654321 AUSTRALIA' +zint -o bar65.svg -b 63 --border=10 -d '87654321 AUSTRALIA' +echo testing Australian Post Reply Paid +zint -o bar66.png -b 66 --border=10 -d 87654321 +zint -o bar66.eps -b 66 --border=10 -d 87654321 +zint -o bar66.svg -b 66 --border=10 -d 87654321 +echo testing Australian Post Routing +zint -o bar67.png -b 67 --border=10 -d 87654321 +zint -o bar67.eps -b 67 --border=10 -d 87654321 +zint -o bar67.svg -b 67 --border=10 -d 87654321 +echo testing Australian Post Redirection +zint -o bar68.png -b 68 --border=10 -d 87654321 +zint -o bar68.eps -b 68 --border=10 -d 87654321 +zint -o bar68.svg -b 68 --border=10 -d 87654321 +echo testing ISBN Code +zint -o bar69.png -b 69 --height=50 --border=10 -d 0333638514 +zint -o bar69.eps -b 69 --height=50 --border=10 -d 0333638514 +zint -o bar69.svg -b 69 --height=50 --border=10 -d 0333638514 +echo testing Royal Mail 4 State +zint -o bar70.png -b 70 --border=10 -d ROYALMAIL +zint -o bar70.eps -b 70 --border=10 -d ROYALMAIL +zint -o bar70.svg -b 70 --border=10 -d ROYALMAIL +echo testing Data Matrix +zint -o bar71.png -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +zint -o bar71.eps -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +zint -o bar71.svg -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +zint -o bar71a.png -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar71a.eps -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar71a.svg -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +echo testing Data Matrix ECC 050 +zint -o bar71b.png --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +zint -o bar71b.eps --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +zint -o bar71b.svg --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" +echo testing EAN-14 +zint -o bar72.png -b 72 --height=50 --border=10 -d 3210987654321 +zint -o bar72.eps -b 72 --height=50 --border=10 -d 3210987654321 +zint -o bar72.svg -b 72 --height=50 --border=10 -d 3210987654321 +echo testing NVE-18 +zint -o bar75.png -b 75 --height=50 --border=10 -d 76543210987654321 +zint -o bar75.eps -b 75 --height=50 --border=10 -d 76543210987654321 +zint -o bar75.svg -b 75 --height=50 --border=10 -d 76543210987654321 +echo testing Japanese Post +zint -o bar76.png -b 76 --border=10 -d "10000131-3-2-503" +zint -o bar76.eps -b 76 --border=10 -d "10000131-3-2-503" +zint -o bar76.svg -b 76 --border=10 -d "10000131-3-2-503" +echo testing Korea Post +zint -o bar77.png -b 77 --height=50 --border=10 -d 123456 +zint -o bar77.eps -b 77 --height=50 --border=10 -d 123456 +zint -o bar77.svg -b 77 --height=50 --border=10 -d 123456 +echo testing DataBar Truncated +zint -o bar78.png -b 29 --height=13 --border=10 -d 1234567890 +zint -o bar78.eps -b 29 --height=13 --border=10 -d 1234567890 +zint -o bar78.svg -b 29 --height=13 --border=10 -d 1234567890 +echo testing DataBar Stacked +zint -o bar79.png -b 79 --border=10 -d 1234567890 +zint -o bar79.eps -b 79 --border=10 -d 1234567890 +zint -o bar79.svg -b 79 --border=10 -d 1234567890 +echo testing DataBar Stacked Omnidirectional +zint -o bar80.png -b 80 --height=69 --border=10 -d 3456789012 +zint -o bar80.eps -b 80 --height=69 --border=10 -d 3456789012 +zint -o bar80.svg -b 80 --height=69 --border=10 -d 3456789012 +echo testing DataBar Expanded Stacked +zint -o bar81.png -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +zint -o bar81.eps -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +zint -o bar81.svg -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" +echo testing Planet 12 Digit +zint -o bar82.png -b 82 --border=10 -d 10987654321 +zint -o bar82.eps -b 82 --border=10 -d 10987654321 +zint -o bar82.svg -b 82 --border=10 -d 10987654321 +echo testing Planet 14 Digit +zint -o bar83.png -b 82 --border=10 -d 3210987654321 +zint -o bar83.eps -b 82 --border=10 -d 3210987654321 +zint -o bar83.svg -b 82 --border=10 -d 3210987654321 +echo testing Micro PDF417 +zint -o bar84.png -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" +zint -o bar84.eps -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" +zint -o bar84.svg -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" +echo testing USPS OneCode 4-State Customer Barcode +zint -o bar85.png -b 85 --border=10 -d 01234567094987654321 +zint -o bar85.eps -b 85 --border=10 -d 01234567094987654321 +zint -o bar85.svg -b 85 --border=10 -d 01234567094987654321 +echo testing Plessey Code with bidirectional reading support +zint -o bar86.png -b 86 --height=50 --border=10 -d 87654321 +zint -o bar86.eps -b 86 --height=50 --border=10 -d 87654321 +zint -o bar86.svg -b 86 --height=50 --border=10 -d 87654321 +echo testing Telepen Numeric +zint -o bar87.png -b 87 --height=50 --border=10 -d 87654321 +zint -o bar87.eps -b 87 --height=50 --border=10 -d 87654321 +zint -o bar87.svg -b 87 --height=50 --border=10 -d 87654321 +echo testing ITF-14 +zint -o bar89.png -b 89 --height=50 --border=10 -d 3210987654321 +zint -o bar89.eps -b 89 --height=50 --border=10 -d 3210987654321 +zint -o bar89.svg -b 89 --height=50 --border=10 -d 3210987654321 +echo testing KIX Code +zint -o bar90.png -b 90 --border=10 -d '1231FZ13Xhs' +zint -o bar90.eps -b 90 --border=10 -d '1231FZ13Xhs' +zint -o bar90.svg -b 90 --border=10 -d '1231FZ13Xhs' +echo testing Aztec Code +zint -o bar92.png -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" +zint -o bar92.eps -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" +zint -o bar92.svg -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" +zint -o bar92a.png -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar92a.eps -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +zint -o bar92a.svg -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" +echo testing DAFT Code +zint -o bar93.png -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" +zint -o bar93.eps -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" +zint -o bar93.svg -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" +echo testing Micro QR Code +zint -o bar97.png -b 97 --border=10 -d "MicroQR Code" +zint -o bar97.eps -b 97 --border=10 -d "MicroQR Code" +zint -o bar97.svg -b 97 --border=10 -d "MicroQR Code" +zint -o bar97k.png -b 97 --kanji --border=10 -d "小さい" +zint -o bar97k.eps -b 97 --kanji --border=10 -d "小さい" +zint -o bar97k.svg -b 97 --kanji --border=10 -d "小さい" +echo testing HIBC LIC 128 +zint -o bar98.png -b 98 --border=10 -d "A99912345/9901510X3" +zint -o bar98.eps -b 98 --border=10 -d "A99912345/9901510X3" +zint -o bar98.svg -b 98 --border=10 -d "A99912345/9901510X3" +echo testing HIBC LIC 39 +zint -o bar99.png -b 99 --border=10 -d "A123BJC5D6E71" +zint -o bar99.eps -b 99 --border=10 -d "A123BJC5D6E71" +zint -o bar99.svg -b 99 --border=10 -d "A123BJC5D6E71" +echo testing HIBC LIC Data Matrix +zint -o bar102.png -b 102 --border=10 -d "A99912345/9901510X3" +zint -o bar102.eps -b 102 --border=10 -d "A99912345/9901510X3" +zint -o bar102.svg -b 102 --border=10 -d "A99912345/9901510X3" +echo testing HIBC LIC QR-Code +zint -o bar104.png -b 104 --border=10 -d "A99912345/9901510X3" +zint -o bar104.eps -b 104 --border=10 -d "A99912345/9901510X3" +zint -o bar104.svg -b 104 --border=10 -d "A99912345/9901510X3" +echo testing HIBC LIC PDF417 +zint -o bar106.png -b 106 --border=10 -d "A99912345/9901510X3" +zint -o bar106.eps -b 106 --border=10 -d "A99912345/9901510X3" +zint -o bar106.svg -b 106 --border=10 -d "A99912345/9901510X3" +echo testing HIBC LIC MicroPDF417 +zint -o bar108.png -b 108 --border=10 -d "A99912345/9901510X3" +zint -o bar108.eps -b 108 --border=10 -d "A99912345/9901510X3" +zint -o bar108.svg -b 108 --border=10 -d "A99912345/9901510X3" +echo testing HIBC LIC Aztec Code +zint -o bar112.png -b 112 --border=10 -d "A99912345/9901510X3" +zint -o bar112.eps -b 112 --border=10 -d "A99912345/9901510X3" +zint -o bar112.svg -b 112 --border=10 -d "A99912345/9901510X3" +echo testing Aztec Runes +zint -o bar128.png -b 128 --border=10 -d 125 +zint -o bar128.eps -b 128 --border=10 -d 125 +zint -o bar128.svg -b 128 --border=10 -d 125 +echo testing Code 23 +zint -o bar129.png -b 129 --border=10 -d "12345678" +zint -o bar129.eps -b 129 --border=10 -d "12345678" +zint -o bar129.svg -b 129 --border=10 -d "12345678" +echo testing EAN-8 Composite with CC-A +zint -o bar130.png -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" +zint -o bar130.eps -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" +zint -o bar130.svg -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" +echo testing EAN-13 Composite with CC-A +zint -o bar130a.png -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" +zint -o bar130a.eps -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" +zint -o bar130a.svg -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" +echo testing UCC/EAN-128 Composite with CC-A +zint -o bar131.png -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" +zint -o bar131.eps -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" +zint -o bar131.svg -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" +echo testing UCC/EAN-128 Composite with CC-C +zint -o bar131a.png -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" +zint -o bar131a.eps -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" +zint -o bar131a.svg -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" +echo testing DataBar-14 Composite with CC-A +zint -o bar132.png -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" +zint -o bar132.eps -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" +zint -o bar132.svg -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" +echo testing DataBar Limited Composite with CC-B +zint -o bar133.png -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" +zint -o bar133.eps -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" +zint -o bar133.svg -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" +echo testing DataBar Expanded Composite with CC-A +zint -o bar134.png -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" +zint -o bar134.eps -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" +zint -o bar134.svg -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" +echo testing UPC-A Composite with CC-A +zint -o bar135.png -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" +zint -o bar135.eps -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" +zint -o bar135.svg -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" +echo testing UPC-E Composite with CC-A +zint -o bar136.png -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" +zint -o bar136.eps -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" +zint -o bar136.svg -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" +echo testing DataBar-14 Stacked Composite with CC-A +zint -o bar137.png -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +zint -o bar137.eps -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +zint -o bar137.svg -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +echo testing DataBar-14 Stacked Omnidirectional Composite with CC-A +zint -o bar138.png -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +zint -o bar138.eps -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +zint -o bar138.svg -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" +echo testing DataBar Expanded Stacked Composite with CC-A +zint -o bar139.png -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" +zint -o bar139.eps -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" +zint -o bar139.svg -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" +echo testing Channel Code +zint -o bar140.png -b 140 --height=100 --border=10 -d "12345" +zint -o bar140.eps -b 140 --height=100 --border=10 -d "12345" +zint -o bar140.svg -b 140 --height=100 --border=10 -d "12345" +echo testing Code One +zint -o bar141.png -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +zint -o bar141.eps -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +zint -o bar141.svg -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +echo testing Grid Matrix +zint -o bar142.png -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint" +zint -o bar142.eps -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint" +zint -o bar142.svg -b 142 --border=10 -d "Demonstration Grid Matrix generated by libzint" +echo testing PNG rotation +zint -o barrot0.png -b 130 --height=50 --border=10 --mode=1 --rotate=0 --primary=331234567890+01234 -d "[99]1234-abcd" +zint -o barrot90.png -b 130 --height=50 --border=10 --mode=1 --rotate=90 --primary=331234567890+01234 -d "[99]1234-abcd" +zint -o barrot180.png -b 130 --height=50 --border=10 --mode=1 --rotate=180 --primary=331234567890+01234 -d "[99]1234-abcd" +zint -o barrot270.png -b 130 --height=50 --border=10 --mode=1 --rotate=270 --primary=331234567890+01234 -d "[99]1234-abcd" +echo testing Extended ASCII support +zint -o barext.png --height=50 --border=10 -d "größer" +zint -o barext.svg --height=50 --border=10 -d "größer" diff --git a/frontend/zint.rc b/frontend/zint.rc new file mode 100644 index 00000000..1e35c4c8 --- /dev/null +++ b/frontend/zint.rc @@ -0,0 +1,85 @@ +#define WIN32_LEAN_AND_MEAN + +#include + +#include + + + +#ifdef GCC_WINDRES + +VS_VERSION_INFO VERSIONINFO + +#else + +VS_VERSION_INFO VERSIONINFO + +#endif + + FILEVERSION 2,3,0,0 + + PRODUCTVERSION 2,3,0,0 + + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + +#ifdef _DEBUG + + FILEFLAGS VS_FF_DEBUG + +#else + + FILEFLAGS 0 + +#endif + + FILEOS VOS_NT_WINDOWS32 + + FILETYPE VFT_APP + + FILESUBTYPE VFT2_UNKNOWN + +BEGIN + + BLOCK "StringFileInfo" + + BEGIN + + BLOCK "040904E4" + + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + + VALUE "FileDescription", "zint barcode generator\0" + + VALUE "FileVersion", "2.3.0.0\0" + + VALUE "InternalName", "zint.exe\0" + + VALUE "LegalCopyright", "Copyright 2009 Robin Stuart & BogDan Vatra\0" + + VALUE "OriginalFilename", "zint.exe\0" + + VALUE "ProductName", "zint\0" + + VALUE "ProductVersion", "2.3.0.0\0" + + VALUE "License", "GNU General Public License version 3\0" + + VALUE "WWW", "http://www.sourceforge.net/projects/zint\0" + + END + + END + + BLOCK "VarFileInfo" + + BEGIN + + VALUE "Translation", 0x0409, 1250 + + END + +END + +100 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "zint_black.ico" \ No newline at end of file diff --git a/frontend/zint_black.ico b/frontend/zint_black.ico new file mode 100644 index 0000000000000000000000000000000000000000..84e8b70282a719dc50c8e6e520e23cd641ae3f1f GIT binary patch literal 25698 zcmeHP30xFM*8g|UaH=pIiL7EAF>7$u06C0q1=yW;~u-gA%jJK%LKhENRtmPM-0h$A~MFLbtD@i3~O``swxFp?x0o`@J z9?nHn^}Zf<)dL3DvFbP#V>MJ+eKl&6e34FV;q#nMf!ewL-#pLxU?riUrcj^PMN=7j zyC-7@sg_P6MtNOT>Jo?XJkb(_D5`uNGF1fFKrN_YV`Bpq>Dr(JY~ciZu>&08ip~yN zgvT(%yw8xfjv+gjA^$XA6Yj1DU3`FkVL)Is5S|K5$pYr&0q^MHvW&rRJwy05!tWz| z9^uas{)z(Mm+&JAKaKE<2)~Z-2MAwG_%gzm6TX7*KM}r?@V5wGrNH~pf*JM<5FHGp zP64vwfxHwzzaB1ZJN(#QgtIRZ!%iTLokcdgfPAKJh~I}6=`at%dl9}b;rkOli0~r_ zKc4V0gij{?YQk?N{67hQz8)`9_-YE@mcqBE@Es}q4ivtVp5`fYg+KGdcovR$va^h( zVF$~`H!Qy%?@oBHFgjk*fPX3woCW+3;iu|>IOc-)2)~N(nS|F7{y5>kQ{a0MJ}3+r z7Y)Rw0!y-h4TRsX2gT`v0>T#(zJ&1K6TXb_HxziEUNro{H2m>2{8$?P5*q#n8vX%V z^N+iL75IUj3kUly2JCVgm_8fqMt*(#KJJ94)J6LeK7jC}2v4^3(+MB%0`{IC*y?bw zEiqvG(#U2u*oFKCJY6rt)P%PsyaVAK3Ez?MbXb_y6)eCHY(hBLycn>hX<$3E!M@3F zz|&j}LuW*z2U5`oS?G^Ex)SO!9L!}Lm|rwl_#&{FRbXjb!Lq*u%WpV-KD3&I5hfbJ zgr7|KIKnR>{3nFpM)qqBKIK$!?vX#b=o6T@KzX5M*ZD_ts zq(W9WFyAZ*)~MDmf~7~X1w%A_FVTXI8!=4}P!CA4 zG;?+>GcLNqT8lLU_bCJIXl1&W5%FiGyL%h8RN_YHM&!Oz=Q=-2s>nKLT1v7`quzM;X)A_8BXp zadK~_=>5(E_ovLaH>F!kHHfPD=TtRp>G{;t(-YcmJuz_LK)n3&%NRH26~x5E;LVs= z>vO90Io0}{YJErIYBnv%Id#dYp3XyI~`Op8%oL@L@wD>OK&l zCqusPI^oUq*XScQx8XwuzZ7@+hjXDz&U`Bzjv3K~y<76I_ve=my+3h^(+6iieyrU8 z_@8cedF9CZFaPfQ-cy-VhmP*uDQxad`#~3$CwL{TN!iz_--raSTRR4)9e)Fpf0(xg z$5IgFD@aiy_NlSJ0ctnc_kt!E+JcwxM(By%g?;R*dvy;v@yb!vr=tGA^xK)0-qQK+ zs!m)#wZhI3uQ%XNi_uSB9V!fP3jNe!te~_xqk}F}-&;4jtcS28p`*Q_r)7Ps%BF33>fyuRS|z@$@C$_PQs1LLB0r z+|%VK8&EwGj`PZbPChebLeaR~{MVMuPp`bO`?nXdr`yDoQa0u0@LIWeY&~a-(aQ^; zO~v-_bM9m=!G!gdPLE>dyji)MdV=NT?!IwwV%cA$&4S0dynx^}>Z_Y$UG)iD^_j&3 zZHkt!oRn0#yLe^(@Pg4;5wbtCH%{I5i5flw-zMUdlq9EZ2_5^OVpt%K9}ct=Jk(MB zj5d;w+D2`d@$aRv{}i&mC|^2ZtEz);88Y6%Vuzrv!dMraaIzwoacp)OMVOLj#m2Ug}+Rpu3+KX9=)yV7It&g(ex zr!>p^_uyf0p|ib9-jO3*O414 z9JcJ*9>=kvc-RXS8h(H@!m?y+caatb&)icH8t0#Tb?)Ve zqS$q-{~p_W+NR4Rv*$j4Cp>=NXHI?N1FJp|(*4uR66ZVjfA#l)|2QN@Zpu7==?V8Y z4xMIOBW7=!y)Py8@moGcA5=w_{c!3-Y`>DDatK;kcxFo|CY(IiE$25szic z6E;)5_UZ?JiOb3B*f~_ZmYax=_N>W?b)ENktzOv96*K||15 z;jC{%_u8ed-BpqMh||YdwdGg2ol)Q}XlT`z_<~L7FIKaYSw6N!f2%1hf7%6;ADUaU zbRj%#(Er7s8K>h&3%y8-zk!7>hT!p=zuLg@^@bb5dYc6dT6w+rsdFa>g(2##jY(%B zh!|WtT58=^UY<<($l8fLtL$}ug073b;)*tQJVJ&F1*>a3=OpK=*4&sG9+!~t`nbK@ zLvk1Yes1~bJ9*^`4qv9_q6E?qc;m4(~m%dw>G^T3Y z=+N#9m<;MeN#zRcqkB2$S99o|;*1d{W9EsrSo!+E^&w#a2d9hGC?HUtHax2e+iMM5r6%dtnn-6ojm_qh+6aCdbu_>udVsF=HJ-7Xe!S-e;&;FQ-9prOT)tZ zhxQV7eH;&Z{Pf;KQ_p#>*X|0vukk>~PYJao{`PnbERA2*Z)`3xfnIy!RgoKGx=Oj+ zHm27Uo{YDY8rn96Z;q}Z*068NuPK?*jwwA^)*O8$)>vEiVF|6Z;|Mp4F$8QX##pSz zculpZ)RXNfdFI;9!N}Ogs5#$;a@md{-&FrzFx*~Kiz(lRvRa$;-k%}gR9}w6l#Vf( zjB5%thBwBOZ5fj_#=94cY)i&AmCCrrsM1bjI!eB!`bsQs-)k|nBlivM$$Vqf5?y0> z)`8y2G&IrzePh0jxiO|^l1J~=wnqHMVl~Gz88?BIa&xxYL{9H2D`Pa*Zj%_zI5iiu zQf|gnn~0V1nQOO6fM%SUi&-f*W2#NW%J|H+l>wU5ZI5zm{QrMVZtY`a&A&DO&6#u7 z`O{A35B-)-bB<$MVgH-vk8&*5b}MF}?%fhP5o=2ey!*??q9VKI-u;#3zvy>>wXJyM zA4FF|8?Uui|1@jb;uzeWtk(RS$bT!G&?fWW3jRe?bFanyo4HSHasTAN)cCoqrHeWL z#$q5|{k&1eXJ|_)Gu1Z48SBe2zHv;8+E1|FlaIONzZl^N>GcFa*zIHgQ!N69zZrr&$v{MIN&{gdO? z^3TWESPZQ({s+Z>V>xO`zB2zU>8CNu9$#3x9_&M5I{*|%(qS}hz01+g* zq54@R1xZFa$M~R zFUMpFRmN`#PS#c8d0Q?rzp=g{U#Ty*Wy*EsHm8QgKvw?@AoIDt+%|?+%4OTKzG2^x zFUy-kWo%u=Noc4k)aP~4)QrJz_skf4kZS3q OjKQqDt}1mo_WuB*tNslD literal 0 HcmV?d00001 diff --git a/frontend_qt4/CMakeLists.txt b/frontend_qt4/CMakeLists.txt new file mode 100644 index 00000000..335831fb --- /dev/null +++ b/frontend_qt4/CMakeLists.txt @@ -0,0 +1,26 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(zint-qt) + +include_directories(BEFORE "${CMAKE_SOURCE_DIR}/backend" "${CMAKE_SOURCE_DIR}/backend_qt4") + +set(zint-qt_SRCS barcodeitem.cpp main.cpp mainwindow.cpp datawindow.cpp sequencewindow.cpp exportwindow.cpp) +QT4_WRAP_CPP(zint-qt_SRCS mainwindow.h datawindow.h sequencewindow.h exportwindow.h) + +QT4_WRAP_UI(zint-qt_SRCS mainWindow.ui extData.ui extSequence.ui extExport.ui) +# grpAztec.ui grpC39.ui grpDM.ui grpMSICheck.ui +# grpC128.ui grpChannel.ui grpMicroPDF.ui grpPDF417.ui +# grpC16k.ui grpCodablock.ui grpMQR.ui grpQR.ui +# grpMaxicode.ui) + +QT4_ADD_RESOURCES(zint-qt_SRCS resources.qrc) + +add_executable(zint-qt ${zint-qt_SRCS}) +add_dependencies(zint-qt QZint zint) + +link_directories( "${CMAKE_BINARY_DIR}/backend" "${CMAKE_BINARY_DIR}/backend_qt4" ) + +target_link_libraries(zint-qt zint QZint ${QT_QTUITOOLS_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} + ${QT_QTCORE_LIBRARY} ) + +install(TARGETS zint-qt DESTINATION "${BIN_INSTALL_DIR}" RUNTIME) diff --git a/frontend_qt4/barcodeitem.cpp b/frontend_qt4/barcodeitem.cpp new file mode 100644 index 00000000..3639c2f5 --- /dev/null +++ b/frontend_qt4/barcodeitem.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * * + * 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, see . * + ***************************************************************************/ + +#include +#include "barcodeitem.h" + +BarcodeItem::BarcodeItem() + : QGraphicsItem() +{ + w=550; + h=230; +} + + +BarcodeItem::~BarcodeItem() +{ +} + +QRectF BarcodeItem::boundingRect() const +{ + return QRectF(0, 0, w, h); +} + +void BarcodeItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) +{ + bc.render(*painter,boundingRect(),ar); +} + + diff --git a/frontend_qt4/barcodeitem.h b/frontend_qt4/barcodeitem.h new file mode 100644 index 00000000..165e654e --- /dev/null +++ b/frontend_qt4/barcodeitem.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * * + * 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, see . * + ***************************************************************************/ + +#ifndef BARCODEITEM_H +#define BARCODEITEM_H + +#include +#include + +/** + @author BogDan Vatra +*/ + +class BarcodeItem : public QGraphicsItem +{ +public: + BarcodeItem(); + ~BarcodeItem(); + QRectF boundingRect() const; + void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0); + +public: + mutable Zint::QZint bc; + int w,h; + Zint::QZint::AspectRatioMode ar; +}; + +#endif diff --git a/frontend_qt4/datawindow.cpp b/frontend_qt4/datawindow.cpp new file mode 100644 index 00000000..5eb96cb7 --- /dev/null +++ b/frontend_qt4/datawindow.cpp @@ -0,0 +1,103 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include +#include + +#include "datawindow.h" +#include + +DataWindow::DataWindow() +{ + setupUi(this); + + connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); + connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); +} + +DataWindow::DataWindow(QString input) +{ + setupUi(this); + txtDataInput->setPlainText(input); + txtDataInput->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + + connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); + connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); + connect(btnFromFile, SIGNAL( clicked( bool )), SLOT(from_file())); +} + +DataWindow::~DataWindow() +{ +} + +void DataWindow::quit_now() +{ + Valid = 0; + close(); +} + +void DataWindow::clear_data() +{ + txtDataInput->clear(); +} + +void DataWindow::okay() +{ + Valid = 1; + DataOutput = txtDataInput->toPlainText(); + close(); +} + +void DataWindow::from_file() +{ + //QString fileName; + //QFileDialog fdialog; + QFile file; + + //fdialog.setFileMode(QFileDialog::ExistingFile); + // + //if(fdialog.exec()) { + // fileName = fdialog.selectedFiles().at(0); + //} else { + // return; + //} + + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open File"), + "./", + tr("All Files (*);;Text Files (*.txt)")); + if (fileName.isEmpty()) + return; + + file.setFileName(fileName); + if(!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); + return; + } + + QByteArray outstream = file.readAll(); + + txtDataInput->setPlainText(QString(outstream)); + file.close(); +} \ No newline at end of file diff --git a/frontend_qt4/datawindow.h b/frontend_qt4/datawindow.h new file mode 100644 index 00000000..8a6d7ecc --- /dev/null +++ b/frontend_qt4/datawindow.h @@ -0,0 +1,43 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +#ifndef DATAWINDOW_H +#define DATAWINDOW_H + +#include "ui_extData.h" + +class DataWindow : public QDialog, private Ui::DataDialog +{ + Q_OBJECT + +public: + DataWindow(); + DataWindow(QString input); + ~DataWindow(); + int Valid; + QString DataOutput; + +private slots: + void quit_now(); + void clear_data(); + void okay(); + void from_file(); +}; + +#endif diff --git a/frontend_qt4/exportwindow.cpp b/frontend_qt4/exportwindow.cpp new file mode 100644 index 00000000..40c27b6e --- /dev/null +++ b/frontend_qt4/exportwindow.cpp @@ -0,0 +1,138 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include + +#include "exportwindow.h" +#include + +ExportWindow::ExportWindow() +{ + setupUi(this); + linDestPath->setText(QDir::toNativeSeparators(QDir::homePath())); + + connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnOK, SIGNAL( clicked( bool )), SLOT(process())); + connect(btnDestPath, SIGNAL( clicked( bool )), SLOT(get_directory())); +} + +ExportWindow::~ExportWindow() +{ + +} + +void ExportWindow::quit_now() +{ + close(); +} + +void ExportWindow::get_directory() +{ + QString directory; + QFileDialog fdialog; + + fdialog.setFileMode(QFileDialog::Directory); + + if(fdialog.exec()) { + directory = fdialog.selectedFiles().at(0); + } else { + return; + } + + linDestPath->setText(QDir::toNativeSeparators(directory)); +} + +void ExportWindow::process() +{ + QString fileName; + QString dataString; + QString suffix; + int lines, i, j, inputpos, datalen; + + lines = output_data.count(QChar('\n'), Qt::CaseInsensitive); + inputpos = 0; + + switch(cmbFileFormat->currentIndex()) { + case 0: suffix = ".png"; break; + case 1: suffix = ".eps"; break; + case 2: suffix = ".svg"; break; + } + + for(i = 0; i < lines; i++) { + datalen = 0; + for(j = inputpos; ((output_data[j] != '\n') && (j < output_data.length())); j++) { + datalen++; + } + dataString = output_data.mid(inputpos, datalen); + switch(cmbFileName->currentIndex()) { + case 0: { /* Same as Data (URL Escaped) */ + QString url_escaped; + int m; + char name_char; + QChar name_qchar; + + for(m = 0; m < dataString.length(); m++) { + name_qchar = dataString[m]; + name_char = name_qchar.toAscii(); + + switch(name_char) { + case '\\': url_escaped += "%5C"; break; + case '/': url_escaped += "%2F"; break; + case ':': url_escaped += "%3A"; break; + case '*': url_escaped += "%2A"; break; + case '?': url_escaped += "%3F"; break; + case '"': url_escaped += "%22"; break; + case '<': url_escaped += "%3C"; break; + case '>': url_escaped += "%3E"; break; + case '|': url_escaped += "%7C"; break; + case '%': url_escaped += "%25"; break; + default: url_escaped += name_qchar; break; + } + } + fileName = linDestPath->text() + QDir::separator() + linPrefix->text() + url_escaped + suffix; + } + break; + case 1: { /* Formatted Serial Number */ + QString biggest, this_val, outnumber; + int number_size, val_size, m; + + biggest = QString::number(lines + 1); + number_size = biggest.length(); + this_val = QString::number(i + 1); + val_size = this_val.length(); + + for(m = 0; m < (number_size - val_size); m++) { + outnumber += QChar('0'); + } + + outnumber += this_val; + + fileName = linDestPath->text() + QDir::separator() + linPrefix->text() + outnumber + suffix; + } + break; + } + barcode->bc.setText(dataString.toAscii().data()); + barcode->bc.save_to_file(fileName.toAscii().data()); + inputpos += datalen + 1; + } + close(); +} \ No newline at end of file diff --git a/frontend_qt4/exportwindow.h b/frontend_qt4/exportwindow.h new file mode 100644 index 00000000..14a2fd57 --- /dev/null +++ b/frontend_qt4/exportwindow.h @@ -0,0 +1,42 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +#ifndef EXPORTWINDOW_H +#define EXPORTWINDOW_H + +#include "ui_extExport.h" +#include "barcodeitem.h" + +class ExportWindow : public QDialog, private Ui::ExportDialog +{ + Q_OBJECT + +public: + ExportWindow(); + ~ExportWindow(); + BarcodeItem *barcode; + QString output_data; + +private slots: + void quit_now(); + void process(); + void get_directory(); +}; + +#endif \ No newline at end of file diff --git a/frontend_qt4/extData.ui b/frontend_qt4/extData.ui new file mode 100644 index 00000000..a218b731 --- /dev/null +++ b/frontend_qt4/extData.ui @@ -0,0 +1,98 @@ + + + DataDialog + + + + 0 + 0 + 400 + 300 + + + + Input Data + + + true + + + + + 10 + 20 + 381 + 221 + + + + + + + 10 + 250 + 381 + 41 + + + + + + + From File... + + + + + + + Reset + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + OK + + + + + + + Cancel + + + + + + + + + 10 + 0 + 56 + 16 + + + + Data + + + + + + diff --git a/frontend_qt4/extExport.ui b/frontend_qt4/extExport.ui new file mode 100644 index 00000000..e3a71cd3 --- /dev/null +++ b/frontend_qt4/extExport.ui @@ -0,0 +1,178 @@ + + + ExportDialog + + + + 0 + 0 + 450 + 170 + + + + Export Barcodes + + + + + 140 + 10 + 261 + 22 + + + + + + + 140 + 40 + 301 + 22 + + + + bcs_ + + + + + + 140 + 70 + 301 + 22 + + + + + Same as Data + + + + + Serial Number + + + + + + + 140 + 100 + 301 + 22 + + + + + Portable Network Graphic (*.png) + + + + + Encapsulated Post Script (*.eps) + + + + + Scalable Vector Graphic (*.svg) + + + + + + + 410 + 10 + 30 + 25 + + + + ... + + + + + + 10 + 10 + 121 + 16 + + + + Destination Path: + + + + + + 10 + 40 + 111 + 16 + + + + File Name Prefix: + + + + + + 10 + 70 + 111 + 16 + + + + File Name: + + + + + + 10 + 100 + 111 + 16 + + + + File Format: + + + + + + 360 + 130 + 80 + 26 + + + + Cancel + + + + + + 270 + 130 + 80 + 26 + + + + OK + + + + + + diff --git a/frontend_qt4/extSequence.ui b/frontend_qt4/extSequence.ui new file mode 100644 index 00000000..2d353a71 --- /dev/null +++ b/frontend_qt4/extSequence.ui @@ -0,0 +1,272 @@ + + + SequenceDialog + + + + 0 + 0 + 530 + 300 + + + + Sequence Export + + + true + + + + + 10 + 10 + 261 + 241 + + + + Create Sequence + + + + false + + + + 140 + 200 + 111 + 26 + + + + Export... + + + + + + 140 + 140 + 111 + 26 + + + + Create + + + + + + 140 + 20 + 111 + 22 + + + + 1 + + + true + + + + + + 140 + 110 + 111 + 22 + + + + $$$$$$ + + + + + + 140 + 50 + 111 + 22 + + + + 10 + + + + + + 140 + 170 + 111 + 26 + + + + Import... + + + + + + 10 + 20 + 151 + 20 + + + + Start Value: + + + + + + 10 + 50 + 171 + 16 + + + + End Value: + + + + + + 10 + 80 + 171 + 16 + + + + Increment By: + + + + + + 10 + 110 + 171 + 16 + + + + Format: + + + + + + 10 + 140 + 161 + 16 + + + + Sequence: + + + + + + 10 + 170 + 161 + 16 + + + + Sequence File: + + + + + + 10 + 200 + 161 + 16 + + + + Generate Bar Codes: + + + + + + 140 + 80 + 113 + 22 + + + + 1 + + + + + + + 280 + 10 + 241 + 241 + + + + Sequence Preview + + + + + 10 + 20 + 221 + 171 + + + + + + + 150 + 200 + 80 + 26 + + + + Reset + + + + + + + 440 + 260 + 80 + 26 + + + + Close + + + + + + diff --git a/frontend_qt4/frontend_qt4.pro b/frontend_qt4/frontend_qt4.pro new file mode 100644 index 00000000..2faf3233 --- /dev/null +++ b/frontend_qt4/frontend_qt4.pro @@ -0,0 +1,31 @@ +###################################################################### +# Automatically generated by qmake (2.01a) sub 29. kol 22:15:57 2009 +###################################################################### + + +TEMPLATE = app +TARGET = +DEPENDPATH += . debug release +INCLUDEPATH += . + +# Input +HEADERS += barcodeitem.h mainwindow.h +FORMS += grpAztec.ui \ + grpC128.ui \ + grpC16k.ui \ + grpC39.ui \ + grpC49.ui \ + grpChannel.ui \ + grpCodablock.ui \ + grpCodeOne.ui \ + grpDM.ui \ + grpMaxicode.ui \ + grpMicroPDF.ui \ + grpMQR.ui \ + grpMSICheck.ui \ + grpPDF417.ui \ + grpQR.ui \ + mainWindow.ui +TRANSLATIONS = frontend_de.ts +SOURCES += barcodeitem.cpp main.cpp mainwindow.cpp +RESOURCES += resources.qrc diff --git a/frontend_qt4/frontend_vc8.pro b/frontend_qt4/frontend_vc8.pro new file mode 100644 index 00000000..77d8c447 --- /dev/null +++ b/frontend_qt4/frontend_vc8.pro @@ -0,0 +1,40 @@ +TEMPLATE = vcapp +TARGET = qtZint +CONFIG += warn_on \ + thread \ + qt \ + uitools + +FORMS = mainWindow.ui \ + extSequence.ui \ + extExport.ui \ + extData.ui + +HEADERS = mainwindow.h \ + barcodeitem.h \ + datawindow.h \ + exportwindow.h \ + sequencewindow.h + +SOURCES = main.cpp \ + mainwindow.cpp \ + barcodeitem.cpp \ + datawindow.cpp \ + exportwindow.cpp \ + sequencewindow.cpp + +RESOURCES = resources.qrc + +INCLUDEPATH += ../backend_qt4 ../backend + +CONFIG(debug, debug|release) { +LIBPATH += ../backend_qt4/debug +} + +CONFIG(release, debug|release) { +LIBPATH += ../backend_qt4/release +} + +RC_FILE = ./res/qtZint.rc + +LIBS = QtZint2.lib diff --git a/frontend_qt4/grpAztec.ui b/frontend_qt4/grpAztec.ui new file mode 100644 index 00000000..006dee37 --- /dev/null +++ b/frontend_qt4/grpAztec.ui @@ -0,0 +1,339 @@ + + + grpAztec + + + + 0 + 0 + 461 + 237 + + + + Form + + + + + + + + A&utomatic Resizing + + + true + + + + + + + Adjust Si&ze To: + + + + + + + false + + + + 15 x 15 Compact + + + + + 19 x 19 Compact + + + + + 23 x 23 Compact + + + + + 27 x 27 Compact + + + + + 19 x 19 + + + + + 23 x 23 + + + + + 27 x 27 + + + + + 31 x 31 + + + + + 37 x 37 + + + + + 41 x 41 + + + + + 45 x 45 + + + + + 49 x 49 + + + + + 53 x 53 + + + + + 57 x 57 + + + + + 61 x 61 + + + + + 67 x 67 + + + + + 71 x 71 + + + + + 75 x 75 + + + + + 79 x 79 + + + + + 83 x 83 + + + + + 87 x 87 + + + + + 91 x 91 + + + + + 95 x 95 + + + + + 101 x 101 + + + + + 105 x 105 + + + + + 109 x 109 + + + + + 113 x 113 + + + + + 117 x 117 + + + + + 121 x 121 + + + + + 125 x 125 + + + + + 131 x 131 + + + + + 135 x 135 + + + + + 139 x 139 + + + + + 143 x 143 + + + + + 147 x 147 + + + + + 151 x 151 + + + + + + + + Add Minimum &Error Correction: + + + + + + + false + + + + 10% + 3 words + + + + + 23% + 3 words + + + + + 36% + 3 words + + + + + 50% + 3 words + + + + + + + + + + Encoding Mode + + + + + 30 + 30 + 453 + 71 + + + + + + + HIBC Aztec Code + + + + + + + GS1 Data Mode + + + + + + + Standard Mode + + + true + + + + + + + + + + + + + radAztecSize + toggled(bool) + cmbAztecSize + setEnabled(bool) + + + 85 + 47 + + + 331 + 47 + + + + + radAztecECC + toggled(bool) + cmbAztecECC + setEnabled(bool) + + + 200 + 80 + + + 366 + 80 + + + + + diff --git a/frontend_qt4/grpC128.ui b/frontend_qt4/grpC128.ui new file mode 100644 index 00000000..69891ac3 --- /dev/null +++ b/frontend_qt4/grpC128.ui @@ -0,0 +1,81 @@ + + + grpC128 + + + + 0 + 0 + 317 + 156 + + + + Form + + + + + + + + S&tandard + + + true + + + + + + + Subset &C Supression + + + + + + + &GS1-128 + + + + + + + &HIBC 128 + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Note: Composite symbols require a</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">GS1-128 linear component.</p></body></html> + + + + + + + Qt::Vertical + + + + 20 + 43 + + + + + + + + + diff --git a/frontend_qt4/grpC16k.ui b/frontend_qt4/grpC16k.ui new file mode 100644 index 00000000..6330d46b --- /dev/null +++ b/frontend_qt4/grpC16k.ui @@ -0,0 +1,55 @@ + + + grpC16k + + + + 0 + 0 + 186 + 123 + + + + Form + + + + + + + + S&tandard Mode + + + true + + + + + + + &GS-1 Data Mode + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpC39.ui b/frontend_qt4/grpC39.ui new file mode 100644 index 00000000..c82aabee --- /dev/null +++ b/frontend_qt4/grpC39.ui @@ -0,0 +1,62 @@ + + + grpC39 + + + + 0 + 0 + 254 + 131 + + + + Form + + + + + + + + &No Check Digit + + + true + + + + + + + &HIBC 39 + + + + + + + &Mod-43 Check Digit + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpC49.ui b/frontend_qt4/grpC49.ui new file mode 100644 index 00000000..abea4f22 --- /dev/null +++ b/frontend_qt4/grpC49.ui @@ -0,0 +1,55 @@ + + + grpC16k + + + + 0 + 0 + 186 + 123 + + + + Form + + + + + + + + S&tandard Mode + + + true + + + + + + + &GS-1 Data Mode + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpChannel.ui b/frontend_qt4/grpChannel.ui new file mode 100644 index 00000000..8b4e84a0 --- /dev/null +++ b/frontend_qt4/grpChannel.ui @@ -0,0 +1,89 @@ + + grpChannel + + + + 0 + 0 + 310 + 78 + + + + Form + + + + + + + + &Number of Channels: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbChannel + + + + + + + + Automatic + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + + + + Qt::Vertical + + + + 20 + 30 + + + + + + + + + diff --git a/frontend_qt4/grpCodablock.ui b/frontend_qt4/grpCodablock.ui new file mode 100644 index 00000000..3df44a44 --- /dev/null +++ b/frontend_qt4/grpCodablock.ui @@ -0,0 +1,62 @@ + + + grpCodablock + + + + 0 + 0 + 372 + 175 + + + + Form + + + + + + + + S&tandard Mode + + + true + + + + + + + &HIBC Codablock-F + + + + + + + &GS-1 Data Mode + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpCodeOne.ui b/frontend_qt4/grpCodeOne.ui new file mode 100644 index 00000000..4fe513f7 --- /dev/null +++ b/frontend_qt4/grpCodeOne.ui @@ -0,0 +1,127 @@ + + + grpChannel + + + + 0 + 0 + 310 + 124 + + + + Form + + + + + + + + S&ymbol Size: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbC1Size + + + + + + + + Automatic + + + + + 16 x 18 (Version A) + + + + + 22 x 22 (Version B) + + + + + 28 x 32 (Version C) + + + + + 40 x 42 (Version D) + + + + + 52 x 54 (Version E) + + + + + 70 x 76 (Version F) + + + + + 104 x 98 (Version G) + + + + + 148 x 134 (Version H) + + + + + 8X height (Version S) + + + + + 16X height (Version T) + + + + + + + + S&tandard Mode + + + true + + + + + + + &GS-1 Data Mode + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpDBExtend.ui b/frontend_qt4/grpDBExtend.ui new file mode 100644 index 00000000..77d17c48 --- /dev/null +++ b/frontend_qt4/grpDBExtend.ui @@ -0,0 +1,105 @@ + + + grpDBExtend + + + + 0 + 0 + 310 + 78 + + + + Form + + + + + + + + &Number of Columns: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbCols + + + + + + + + Automatic + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + + + + + + Qt::Vertical + + + + 20 + 30 + + + + + + + + + diff --git a/frontend_qt4/grpDM.ui b/frontend_qt4/grpDM.ui new file mode 100644 index 00000000..e48f3fab --- /dev/null +++ b/frontend_qt4/grpDM.ui @@ -0,0 +1,434 @@ + + + grpDM + + + + 0 + 0 + 463 + 339 + + + + Form + + + + + + + + Encoding &Mode: + + + cmbDMMode + + + + + + + + ECC 200 (Recommended) + + + + + ECC 000 + + + + + ECC 050 + + + + + ECC 080 + + + + + ECC 100 + + + + + ECC 140 + + + + + + + + + + Non ECC 200 Options + + + + + + Si&ze: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbDMNon200Size + + + + + + + + Automatic + + + + + 9 x 9 + + + + + 11 x 11 + + + + + 13 x 13 + + + + + 15 x 15 + + + + + 17 x 17 + + + + + 19 x 19 + + + + + 21 x 21 + + + + + 23 x 23 + + + + + 25 x 25 + + + + + 27 x 27 + + + + + 29 x 29 + + + + + 31 x 31 + + + + + 33 x 33 + + + + + 35 x 35 + + + + + 37 x 37 + + + + + 39 x 39 + + + + + 41 x 41 + + + + + 43 x 43 + + + + + 45 x 45 + + + + + 47 x 47 + + + + + 49 x 49 + + + + + + + + + + + ECC 200 Options + + + + + + + + S&tandard + + + true + + + + + + + &HIBC Data Matrix + + + + + + + &GS-1 Data Mode + + + + + + + Si&ze: + + + cmbDM200Size + + + + + + + + Automatic + + + + + 10 x 10 + + + + + 12 x 12 + + + + + 14 x 14 + + + + + 16 x 16 + + + + + 18 x 18 + + + + + 20 x 20 + + + + + 22 x 22 + + + + + 24 x 24 + + + + + 26 x 26 + + + + + 32 x 32 + + + + + 36 x 36 + + + + + 40 x 40 + + + + + 44 x 44 + + + + + 48 x 48 + + + + + 52 x 52 + + + + + 64 x 64 + + + + + 72 x 72 + + + + + 80 x 80 + + + + + 88 x 88 + + + + + 96 x 96 + + + + + 104 x 104 + + + + + 120 x 120 + + + + + 132 x 132 + + + + + 144 x 144 + + + + + 8 x 18 + + + + + 8 x 32 + + + + + 12 x 26 + + + + + 12 x 36 + + + + + 16 x 36 + + + + + 16 x 48 + + + + + + + + + + Suppress Rectangular Symbols in Automatic Mode + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpGrid.ui b/frontend_qt4/grpGrid.ui new file mode 100644 index 00000000..1976f044 --- /dev/null +++ b/frontend_qt4/grpGrid.ui @@ -0,0 +1,199 @@ + + + grpGrid + + + + 0 + 0 + 423 + 159 + + + + Form + + + + + + + + A&utomatic Resizing + + + true + + + + + + + Adjust Si&ze To: + + + + + + + false + + + + 18 x 18 (Version 1) + + + + + 30 x 30 (Version 2) + + + + + 42 x 42 (Version 3) + + + + + 54 x 54 (Version 4) + + + + + 66 x 66 (Version 5) + + + + + 78 x 78 (Version 6) + + + + + 90 x 90 (Version 7) + + + + + 102 x 102 (Version 8) + + + + + 114 x 114 (Version 9) + + + + + 126 x 126 (Version 10) + + + + + 138 x 138 (Version 11) + + + + + 150 x 150 (Version 12) + + + + + 162 x 162 (Version 13) + + + + + + + + Add &Error Correction: + + + + + + + false + + + + ~10% + + + + + ~20% + + + + + ~30% + + + + + ~40% + + + + + ~50% + + + + + + + + + + Qt::Vertical + + + + 20 + 50 + + + + + + + + + + radGridSize + toggled(bool) + cmbGridSize + setEnabled(bool) + + + 98 + 54 + + + 279 + 53 + + + + + radGridECC + toggled(bool) + cmbGridECC + setEnabled(bool) + + + 114 + 89 + + + 279 + 89 + + + + + diff --git a/frontend_qt4/grpMQR.ui b/frontend_qt4/grpMQR.ui new file mode 100644 index 00000000..58a7ce2e --- /dev/null +++ b/frontend_qt4/grpMQR.ui @@ -0,0 +1,143 @@ + + grpMQR + + + + 0 + 0 + 423 + 159 + + + + Form + + + + + + + + A&utomatic Resizing + + + true + + + + + + + Adjust Si&ze To: + + + + + + + false + + + + 11 x 11 (Version M1) + + + + + 13 x 13 (Version M2) + + + + + 15 x 15 (Version M3) + + + + + 17 x 17 (Version M4) + + + + + + + + Add &Error Correction: + + + + + + + false + + + + ~20% (Level L) + + + + + ~37% (Level M) + + + + + ~55% (Level Q) + + + + + + + + + + Qt::Vertical + + + + 20 + 50 + + + + + + + + + + radMQRSize + toggled(bool) + cmbMQRSize + setEnabled(bool) + + + 98 + 54 + + + 279 + 53 + + + + + radMQRECC + toggled(bool) + cmbMQRECC + setEnabled(bool) + + + 114 + 89 + + + 279 + 89 + + + + + diff --git a/frontend_qt4/grpMSICheck.ui b/frontend_qt4/grpMSICheck.ui new file mode 100644 index 00000000..5052bc99 --- /dev/null +++ b/frontend_qt4/grpMSICheck.ui @@ -0,0 +1,79 @@ + + grpMSICheck + + + + 0 + 0 + 295 + 79 + + + + Form + + + + + + + + &Check Digit: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbMSICheck + + + + + + + + None + + + + + Mod-10 + + + + + Mod-10 & Mod-10 + + + + + Mod-11 + + + + + Mod-11 & Mod-10 + + + + + + + + + + Qt::Vertical + + + + 20 + 31 + + + + + + + + + diff --git a/frontend_qt4/grpMaxicode.ui b/frontend_qt4/grpMaxicode.ui new file mode 100644 index 00000000..5145b59e --- /dev/null +++ b/frontend_qt4/grpMaxicode.ui @@ -0,0 +1,116 @@ + + + grpMicroPDF + + + + 0 + 0 + 532 + 251 + + + + Form + + + + + + + + Encoding &Mode: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbMaxiMode + + + + + + + false + + + &Primary Data: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + txtMaxiPrimary + + + + + + + + 0 + 0 + + + + 1 + + + + Structured Carrier Message (Mode 2 or 3) + + + + + Standard Symbol, SEC (Mode 4) + + + + + Full ECC Symbol (Mode 5) + + + + + Reader Program, SEC (Mode 6) + + + + + + + + false + + + + 0 + 0 + + + + Primary Data Here! + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpMicroPDF.ui b/frontend_qt4/grpMicroPDF.ui new file mode 100644 index 00000000..27e8f272 --- /dev/null +++ b/frontend_qt4/grpMicroPDF.ui @@ -0,0 +1,97 @@ + + + grpMicroPDF + + + + 0 + 0 + 763 + 376 + + + + Form + + + + + + + + &Number of Data Columns: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbMPDFCols + + + + + + + + Automatic + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + + + + S&tandard + + + true + + + + + + + &HIBC MicroPDF417 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/frontend_qt4/grpPDF417.ui b/frontend_qt4/grpPDF417.ui new file mode 100644 index 00000000..7c9d2427 --- /dev/null +++ b/frontend_qt4/grpPDF417.ui @@ -0,0 +1,276 @@ + + grpPDF417 + + + + 0 + 0 + 390 + 223 + + + + Form + + + + + + + + &Number of Data Columns: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbPDFCols + + + + + + + + Automatic + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + 17 + + + + + 18 + + + + + 19 + + + + + 20 + + + + + + + + &Error Correction Capacity: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + cmbPDFECC + + + + + + + + Automatic + + + + + 2 words + + + + + 4 words + + + + + 8 words + + + + + 16 words + + + + + 32 words + + + + + 64 words + + + + + 128 words + + + + + 256 words + + + + + 512 words + + + + + + + + Ma&ximum Codeword Lengh: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + codewords + + + + + + + 928 + + + 1800 + + + 928 + + + + + + + S&tandard + + + true + + + + + + + &HIBC PDF417 + + + + + + + &Truncated + + + + + + + + + Qt::Vertical + + + + 20 + 52 + + + + + + + + + diff --git a/frontend_qt4/grpQR.ui b/frontend_qt4/grpQR.ui new file mode 100644 index 00000000..0f77101b --- /dev/null +++ b/frontend_qt4/grpQR.ui @@ -0,0 +1,373 @@ + + + grpQR + + + + 0 + 0 + 441 + 238 + + + + Form + + + + + + + + A&utomatic Resizing + + + true + + + + + + + Adjust Si&ze To: + + + + + + + false + + + + 21 x 21 (Version 1) + + + + + 25 x 25 (Version 2) + + + + + 29 x 29 (Version 3) + + + + + 33 x 33 (Version 4) + + + + + 37 x 37 (Version 5) + + + + + 41 x 41 (Version 6) + + + + + 45 x 45 (Version 7) + + + + + 49 x 49 (Version 8) + + + + + 53 x 53 (Version 9) + + + + + 57 x 57 (Version 10) + + + + + 61 x 61 (Version 11) + + + + + 65 x 65 (Version 12) + + + + + 69 x 69 (Version 13) + + + + + 73 x 73 (Version 14) + + + + + 77 x 77 (Version 15) + + + + + 81 x 81 (Version 16) + + + + + 85 x 85 (Version 17) + + + + + 89 x 89 (Version 18) + + + + + 93 x 93 (Version 19) + + + + + 97 x 97 (Version 20) + + + + + 101 x 101 (Version 21) + + + + + 105 x 105 (Version 22) + + + + + 109 x 109 (Version 23) + + + + + 113 x 113 (Version 24) + + + + + 117 x 117 (Version 25) + + + + + 121 x 121 (Version 26) + + + + + 125 x 125 (Version 27) + + + + + 129 x 129 (Version 28) + + + + + 133 x 133 (Version 29) + + + + + 137 x 137 (Version 30) + + + + + 141 x 141 (Version 31) + + + + + 145 x 145 (Version 32) + + + + + 149 x 149 (Version 33) + + + + + 153 x 153 (Version 34) + + + + + 157 x 157 (Version 35) + + + + + 161 x 161 (Version 36) + + + + + 165 x 165 (Version 37) + + + + + 169 x 169 (Version 38) + + + + + 173 x 173 (Version 39) + + + + + 177 x 177 (Version 40) + + + + + + + + Add &Error Correction: + + + + + + + false + + + + ~20% (Level L) + + + + + ~37% (Level M) + + + + + ~55% (Level Q) + + + + + ~65% (Level H) + + + + + + + + + + + 0 + 70 + + + + Data Encoding + + + + + 10 + 30 + 411 + 80 + + + + + + + + 0 + 0 + + + + S&tandard Mode + + + true + + + + + + + &HIBC QR Code + + + + + + + &GS-1 Data Mode + + + + + + gridLayoutWidget + + + + + + + + + radQRSize + toggled(bool) + cmbQRSize + setEnabled(bool) + + + 89 + 39 + + + 255 + 46 + + + + + radQRECC + toggled(bool) + cmbQRECC + setEnabled(bool) + + + 95 + 79 + + + 308 + 79 + + + + + diff --git a/frontend_qt4/images/.directory b/frontend_qt4/images/.directory new file mode 100644 index 00000000..773296a4 --- /dev/null +++ b/frontend_qt4/images/.directory @@ -0,0 +1,3 @@ +[Dolphin] +ShowPreview=true +Timestamp=2010,5,29,7,36,6 diff --git a/frontend_qt4/images/rotateleft.png b/frontend_qt4/images/rotateleft.png new file mode 100644 index 0000000000000000000000000000000000000000..8cfa931986b270eee022af8f2855226638008a35 GIT binary patch literal 1754 zcmV<01||84P)`Fh{;B`%{*;@>?p-#>5OJ>M_qo_Freuwnm)=Aomd z)Ujd12A%hEj7!OZCW=YQLUdxLTGX?%!HFO#3`UNcF#HQM%MtJ6uS+EwP!7IT{R2vL zcJ;pUtfTW04N%+AN<$co95;FDjQQhVuZkvNpaK{g8d6IYon1XBDy_y|-vlh!<%fAJ ze=M~N#*gk{h)K?--%&wKoHW&#RC7B~fB>*X}C_^H^M zn2r^P!?D6H2tS`nL``Fx8iM5eKpTiR0z7;63=(MrHtqNu(=FU#%gsVaMJc?hGvF#p zL4fEsIO02SP0hmA;1sNN3WJaTB^AI-qH#oe8UYxNpEci)ldJ}y%cZV^Hjb(m( zyj}q->qD4nc?90Mx7Fr{L|j~M6+-g(0h$!u$mkJ+eeXKbBog>#7h_KlUj?v&Xd02B zMgR#i2^MMz866Vj%bH;u%7>X(G}b3y zflGNBA{z_96W79vUj$3%Fbcq&=u@JR8UaM#tpZzGfQ1L5u-ox0mf8p7msmc6i22!q zGPp^uqD0Y*Z;$f8=5W!_+ydp`Q}hiC;$~hMPKT!>q$vw2LMgU*T!8L~(d((y8UsX% zL}X7B2t+ zh5DP=OaPb)Xa}&TA(R+KzEDjJ+?ta}lT~8PF&=yaWAU(~`xW!Hj$S-?*p0^f?Wn1L z0O!+JVCi*Hdw__lD)_hFfUPVR4h@&!c|Q%uT6u`<%%y*MSWG(pC11wN=F}8?*<2*O zM{CE?Sm@~Jt?`U;u`x^U;I4CRAOwDS6EP^hd!Yo7w2+h4%rC;fE8wYK-rWj8(H0CsUQlB6Yw z7ZoC=vIwzNCE&?~DDP~4uZkwa@@JN~CxVbww*A+5^OrbDc6(nP--iAW*0}gJt%+ zur1mLB?v{tqrC``??gbm6>cC{djRUHMSb6tIo0ivS9!Q7AtxT6jYL5<%0%_36gNST zc^j_2{+MmQ8N0c@5a2k%yPV)&9Ea~Y?uh6)hfD-$2QX&Ln6XipGtu3vpv|dnk4R6) znLIAintAZL5d`aVF4%sMg-xDzSmfgfpUOC-%ah?<77tb)2MauY!^Q(1F!tPmR3%q) zfW?a!>lqmtO^k@UMh_Tzwv!>l&o6|_We!dkBtk%@Vo3W@+Ek^8hyHM`I7ge$akRub zheL=>$%Yph*%X9E0OSg-Yi@3CU}9o2`E`KeN-_Ke$=FHuIKCze;j$p`yDH4 zZg8sz!AV&h=DKggMkiOqrRIR@BWt^p^dzJpGy%|Gy?XUnQ&ZEaoLB*}^DB{&TZXHd zCE#8oU7m0aHUX!x<)RxLGTAs^6$*Bf2iWy&*kqr<(i1!JjqQHe*!$4Nf7l+QMN*qF z_W?tVn~-Qa(bq&4L_ZN(=^7YXkN)UmyD6)dgiW^iGH>ff%*~*$fD%h%91c3y8nocl%%{qfWx#Ju}~ANbWu7d*|JI-(%RY|3mxG z(~g|3A}mphVuILYixE1!wRb)EaLcK z$w6OOxJTojOo@i)P3Y)a21k;J?J-GM!VSQ(pEx+@8i=GIrR2o%Fw zbO#>N9E6wNhrjYJPAd~|w&W&)3+1pBrDKk%J+|!n6J_PqbbT;I2SW1ACrluW&{kj^ zBft$$#mU$#B$QR+a-kAuRLM9}B><;f0B%VFymRy6lUIOKskdRYpNCcJ51_X08PshZ z^y*_ox8dNz$EeZMwve1N*)C`=U@y!>@SS{!%ge#5OGVm?Qq;7ypzPIC#MBqzgi_Qm z;hcFF^S3#{Y#$dIO%GY1YUCAE(hjWjy$(YTkLko{tp&`T1aOxY;6_CiA|L0$t}q!J z6JlZF6amYS>&RBs;$~wR9LcTl%#p)CuMm5pC783t5&JC8A?fcTM2d5;^h^|@Rb_nw zW3&=5nEdGsb5|j5lvhE}kcCj;E#%6T=!=@Vdhqy3`2L(2vbI{-m8HPzUOobegn8t3 zEI%3u^TRG!dh7~#<@X?XpwLZ#>A)@*A)=q&h0S>Z-G+mMk#O}FQVB_05&n1_iX)G% zf|n%+SCol$JP|3LP1Z~_E-RI~3+(o|3b)Xd{&Qe(FyA#aw!qa_fc59aWRVubt~L%w zDk6x;<$exVhv+V#KX%G^j(6gJ4x+*Fy0@1eJj@tBemw2O<)%!WuNULY<0RNrUxlSA z5`Oh*;46l33kIHqgQIsqarLVXdIUQMT%!`ct?BS>k;0=f6}*=cH&D=N}nV5R$U zypI*mwiIToF~yr()DUMXXmNShBgD1IA?heXN}B>1ZKWvfc!I!!V(kS!I{GsTnjS%{ zBHKtILqu^dgvuPmmCL}(i-)m`4K4nvy_4?s`sXk3x%DN~ceEi#^AK5`6)5Pgq1^9L zp{A=@w_U&p{JYB93Ec!Wp_6{K+Q$Kj89B5#bLGz(Te0$7B5azk;C<23*{+*FJD#DU zTZ(K=9OQ^YxkiQs&Q?g1E2scdoVoH^@}T-UK!U|5BCxXa{2cn!f&Yk@Qb!T)qNYsd6cxD$iA9KJGhu^@- z3WsyP5XtIzxD`iXnVT)PIa$N(I0t(!a&bDv2g0&zuoFk%ly5LCd^ItXa=_Y6cLApO zU&&HDZD_#;n-gS#ZKDz=3%$W_@S_ra1T{DzsV)&t=>qHz^n~Z77+N?oUP{?-<*K~^ zd4(R%6gM(5n$C~9K~K24r;RXkbizXW9dK1ek;if{T&wI5{n8#{wF^QX2H?trRG0;y z#mP&d2oqj^m%vKWO@9!H&Fk|PLvUz6fBEYn2I$KIT{UvT#4pHI8x7Obn?LY3mcBW&**r|X;X3_y#2Op0ts650MzizvbuIq3+cH$% a8UFw|)e>7p%to*P0000bzyLc*)WEN?mb6Qqz6zZOIHgzndOMW_`WO z=)nC*%h`6` x9dF;M7kjz%zv-gecP7SFT`hjW;q3W?ac*?k?yMvo8Pu literal 0 HcmV?d00001 diff --git a/frontend_qt4/images/zoomin.png b/frontend_qt4/images/zoomin.png new file mode 100644 index 0000000000000000000000000000000000000000..8b0daeea4801323d5ca253f7ee4d9215e60903ce GIT binary patch literal 1622 zcmV-c2C4apP);FX zK~z}7#g=VMQ)d*%`RX^m;|KQ!xFyT7eRJ8yGW}qdEiOh;V@zG<=0sK?NZlyd2@Kh+ z;0v3AP*9dXZNl`oeKwYp4EP*j4#GBc_h1@5@< zdKY)r($xo{yPrFyXQ8Jb?frwe-Z#L{lD!MA<~_=_-v^04XV%nv0iS`Yy6b$w~g6O7x`BUU{VfiHXWEj{#WCV5n{4 z>ZTqiMN=u-di&8eIK!1Cf!jC^cA?dz(6eAV^@8 za!RWho!AxRjP&7h3zUr31d{seIk0bfu7Qw{Xic`dkPDD{oj}AvL_JUSCxuhp9q!1< zIXNY9K3G`5{KJQQ?U?QzJOjuv!O)-~_?H$NeU0`Yt$H9Yg6?2M&giO21WP?^~MfKVJXgltY*2J|i#jamj zMwl)nyLX41C6Z7?$zlRGW7fbRvR{EUb}g<* zUlPKT>*BY8!a&|9U|!u2N(K?k9$$s&dp~4<6Zm3?HFZ7^&0BzsuL6D3z6=z4au|do z%MEdYLF~XJgD8*m!&%7-Ajq-75sNiS?*aHftla^=DZ2uMjtd_%2o-~dFfxb> zuc1WhhZ8#jRL_lE1Q5+zh@@=+zCUdZ5ZY8hz(gjNI7Bjo*vTMX$CVI2#DDP=gy{Hb zTWKZ~p9T2FeCjVWpZ|zKWMIif5Gf2|7l+9G+7Hp2{r`ekj(8O^AYM_M{Cy8?^cQSt zA2Nt^22qXqUIt;>h0c?2AZqj5Sal8jvcV?t0r0=tAHk~7 U)bUA|oB#j-07*qoM6N<$f<#*pbpQYW literal 0 HcmV?d00001 diff --git a/frontend_qt4/images/zoomout.png b/frontend_qt4/images/zoomout.png new file mode 100644 index 0000000000000000000000000000000000000000..1575dd24f6da8f5db31756a07b3baf6a8329001d GIT binary patch literal 1601 zcmV-H2EO@;P)3l5#GF3@18Rhi8-_G{OgAPDWSSX#iY!RF2EeuP$AFBZM(L#?h1&}vOqO@$t% z6-H>QuA!o`0lMl&=xZ(fY^-U-RZ}(CbM~^bD(Ndru2kx!>M|{qSM)q-O>;ZyT079t z)`iCQE?7Ex(A?FFmaaZNXR2>T`Bf82O7!MSmkckbMqy#Ow75hKWw{wuO#)BcbiJD= zYwhlb&@;f3(zVb#fR2G7T<;&`&uH}~u-^*>1?ApB$mOL07Yd6}tTFNAv|38iId}s- z))92y80KfXt`|D_eFAacr)Nvc^D8w)C>` z>1oV3owzqQ$Ac14;z_%mub7gOLclV3eUZemiC)nW2)nhCqq$P ztz+Xnk>mb-EG#Z!?!g1T;{MTFu-Rw1IyY^1aQn{RgXR?HijkC*>v;I^6AW!MJW zw9~n}z-`1~wmBWoI>}a@2%WALGMS1X>_%ggwEoxi@`mJhR<1^HaM)%BVof-b%s#O? zzP}R$0Z2u>#4-c~+Cj0*$5?Ri}PHdzvrWj;?_zex2M~ zH3C_fSs*$(7KzEJkV=yf8XC^pEL0%1cJKaiEj=3>oAdsYO)Xzlo*4q+%vW&ezrh{F zS~UIS1C3;z{H6XaF;&*GgaPdQuMWQu{(-7lz72~GGv<5J;4mF3}Od^cng>J`XK4+XCNqs zBWlxoSoO|0u)$Z%La5IA7?_Z82&*v;(k&k%B_VzF0hU7)9a@jujfqIy{t?s{OV}Tm zRJ-WEI@}QZH@=Ic!@tm<7W>w%(SafW|7-jSM=!S;*hl9L00000NkvXXu0mjfZ{hZ; literal 0 HcmV?d00001 diff --git a/frontend_qt4/main.cpp b/frontend_qt4/main.cpp new file mode 100644 index 00000000..9d017bbe --- /dev/null +++ b/frontend_qt4/main.cpp @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * * + * 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, see . * + ***************************************************************************/ + +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + Q_INIT_RESOURCE(resources); + QApplication app(argc, argv); + + MainWindow w; + w.show(); + return app.exec(); +} diff --git a/frontend_qt4/mainWindow.ui b/frontend_qt4/mainWindow.ui new file mode 100644 index 00000000..65915307 --- /dev/null +++ b/frontend_qt4/mainWindow.ui @@ -0,0 +1,793 @@ + + + mainWindow + + + Qt::NonModal + + + + 0 + 0 + 749 + 711 + + + + + 749 + 711 + + + + + 749 + 711 + + + + Zint Barcode Studio + + + + :/images/zint.png:/images/zint.png + + + + + + + + + false + + + Preview + + + + + + + 0 + 0 + + + + false + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Zoom out + + + ... + + + + :/images/zoomout.png:/images/zoomout.png + + + + 22 + 22 + + + + + + + + Adjust zoom + + + + + + 50 + + + 400 + + + 100 + + + Qt::Vertical + + + true + + + false + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Zoom in + + + + :/images/zoomin.png:/images/zoomin.png + + + + 22 + 22 + + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Rotate anti-clockwise + + + + + + + :/images/rotateleft.png:/images/rotateleft.png + + + + 22 + 22 + + + + + + + + Adjust Rotation + + + + + + 360 + + + 15 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 90 + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Rotate clockwise + + + + :/images/rotateright.png:/images/rotateright.png + + + + 22 + 22 + + + + + + + + + + + QLayout::SetMaximumSize + + + + + + + + + S&ymbology: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + bstyle + + + + + + + + 0 + 0 + + + + Select type of barcode to generate. + + + + + + + + + + 0 + 0 + + + + + 16777215 + 350 + + + + false + + + + + + 1 + + + + General + + + + + + + 0 + 0 + + + + &Data to Encode + + + + + + Enter data to be encoded. + + + Your Data Here! + + + + + + + ... + + + + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 400 + + + + Composite Code + + + + + + + + Create a composite symbol. + + + Add &2D Component + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Component &Type: + + + cmbCompType + + + + + + + false + + + + Automatic + + + + + CC-A + + + + + CC-B + + + + + CC-C + + + + + + + + + + + + false + + + 2D Component Data: + + + txtComposite + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 60 + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Your Data Here!</span></p></body></html> + + + false + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Appearance + + + + + + + + &Height: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + heightb + + + + + + + B&order Width: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + bwidth + + + + + + + &Whitespace: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + spnWhitespace + + + + + + + &Printing Scale: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + spnScale + + + + + + + Adjust overall symbol height. + + + X + + + + + + 300 + + + 50 + + + + + + + Adjust width of boundary bars or border. + + + X + + + 0 + + + 16 + + + 0 + + + + + + + Adjust whitespace to left and right of barcode. + + + X + + + + + + + Adjust image size when output to file. + + + + + + 2 + + + 0.500000000000000 + + + 99.500000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + Border Ty&pe: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + btype + + + + + + + + No border + + + + + Bind + + + + + Box + + + + + + + + &Foreground Colour + + + + + + + + + + &Backgound Colour + + + + + + + + + Show Human Readable Text + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + &About Zint + + + + + + + Reset zoom, rotation and colour. + + + &Reset Preview + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Se&quence + + + + + + + Save barcode image to file. + + + &Save + + + + + + + E&xit + + + + + + + + + + + tabMain + txtData + chkComposite + cmbCompType + txtComposite + btnAbout + btnReset + btnSave + btnExit + view + btnZoomOut + scaleSlider + btnZoomIn + btnRotateLeft + rotateSlider + btnRotatRight + + + + + + diff --git a/frontend_qt4/mainwindow.cpp b/frontend_qt4/mainwindow.cpp new file mode 100644 index 00000000..f34711f9 --- /dev/null +++ b/frontend_qt4/mainwindow.cpp @@ -0,0 +1,874 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * Copyright (C) 2009 by Robin Stuart * + * * + * 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, see . * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "datawindow.h" +#include "sequencewindow.h" +#include + +MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) + : QWidget(parent, fl),m_optionWidget(0) +{ + + char bstyle_text[][50] = { + "Australia Post Redirect Code", + "Australia Post Reply-Paid", + "Australia Post Routing Code", + "Australia Post Standard Customer", + "Aztec Code (ISO 24778)", + "Aztec Runes", + "Channel Code", + "Codabar", + "Code 11", + "Code 128 (ISO 15417)", + "Code 16k", + "Code 2 of 5 Data Logic", + "Code 2 of 5 IATA", + "Code 2 of 5 Industrial", + "Code 2 of 5 Interleaved", + "Code 2 of 5 Matrix", + "Code 32 (Italian Pharmacode)", + "Code 39 (ISO 16388)", + "Code 39 Extended", + "Code 49", + "Code 93", + "Code One", + "Databar", + "Databar Expanded", + "Databar Expanded Stacked", + "Databar Limited", + "Databar Stacked", + "Databar Stacked Omnidirectional", + "Data Matrix (ISO 16022)", + "Deutsche Post Identcode", + "Deutsche Post Leitcode", + "Dutch Post KIX", + "EAN-14", + "European Article Number (EAN)", + "Facing Identification Mark (FIM)", + "Flattermarken", + "Grid Matrix", + "ITF-14", + "International Standard Book Number (ISBN)", + "Japanese Postal Barcode", + "Korean Postal Barcode", + "LOGMARS", + "Maxicode (ISO 16023)", + "MicroPDF417 (ISO 24728)", + "Micro QR Code", + "MSI Plessey", + "NVE-18", + "PDF417 (ISO 15438)", + "Pharmacode", + "Pharmacode 2-track", + "Pharma Zentralnummer (PZN)", + "PLANET", + "Postnet", + "QR Code (ISO 18004)", + "Royal Mail 4-state Barcode", + "Telepen", + "Telepen Numeric", + "UK Plessey", + "Universal Product Code (UPC-A)", + "Universal Product Code (UPC-E)", + "USPS One Code" + }; + + /* createActions(); + createMenus(); */ + + setupUi(this); + view->setScene(new QGraphicsScene); + + m_fgcolor=qRgb(0,0,0); + m_bgcolor=qRgb(0xff,0xff,0xff); + for (int i=0;ienumerator(0).keyCount();i++) { + bstyle->addItem(metaObject()->enumerator(0).key(i)); + bstyle->setItemText(i,bstyle_text[i]); + } + bstyle->setCurrentIndex(9); + change_options(); + update_preview(); + view->scene()->addItem(&m_bc); + connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(change_options())); + connect(bstyle, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(heightb, SIGNAL(valueChanged( int )), SLOT(update_preview())); + connect(bwidth, SIGNAL(valueChanged( int )), SLOT(update_preview())); + connect(btype, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(txtData, SIGNAL(textChanged( const QString& )), SLOT(update_preview())); + connect(txtComposite, SIGNAL(textChanged()), SLOT(update_preview())); + connect(chkComposite, SIGNAL(stateChanged( int )), SLOT(composite_enable())); + connect(chkComposite, SIGNAL(stateChanged( int )), SLOT(update_preview())); + connect(cmbCompType, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(rotateSlider, SIGNAL(valueChanged(int)), SLOT(scaleRotate())); + connect(scaleSlider, SIGNAL(valueChanged(int)), SLOT(scaleRotate())); + connect(spnWhitespace, SIGNAL(valueChanged( int )), SLOT(update_preview())); + connect(btnAbout, SIGNAL(clicked( bool )), SLOT(about())); + connect(btnSave, SIGNAL(clicked( bool )), SLOT(save())); + connect(spnScale, SIGNAL(valueChanged( double )), SLOT(change_print_scale())); + connect(btnExit, SIGNAL(clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL(clicked( bool )), SLOT(reset_view())); + connect(btnMoreData, SIGNAL(clicked( bool )), SLOT(open_data_dialog())); + connect(btnSequence, SIGNAL(clicked( bool )), SLOT(open_sequence_dialog())); + connect(chkHRTHide, SIGNAL(stateChanged( int )), SLOT(update_preview())); + connect(btnZoomIn, SIGNAL(clicked(void)), SLOT(zoomIn(void))); + connect(btnZoomOut, SIGNAL(clicked(void)), SLOT(zoomOut(void))); + connect(btnRotateLeft, SIGNAL(clicked(void)), SLOT(rotateLeft(void))); + connect(btnRotatRight, SIGNAL(clicked(void)), SLOT(rotateRight(void))); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::reset_view() +{ + scaleSlider->setSliderPosition( 100 ); + rotateSlider->setSliderPosition( 0 ); + m_fgcolor=qRgb(0,0,0); + m_bgcolor=qRgb(0xff,0xff,0xff); + update_preview(); +} + +void MainWindow::scaleRotate() +{ + view->resetTransform(); + view->rotate(rotateSlider->value()); + view->scale((double)scaleSlider->value()/100,(double)scaleSlider->value()/100); +} + +bool MainWindow::save() +{ + bool status; + + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save Barcode Image"), ".", + tr("Portable Network Graphic (*.png);;Encapsulated Post Script (*.eps);;Scalable Vector Graphic (*.svg)")); + + if (fileName.isEmpty()) + return false; + + status = m_bc.bc.save_to_file(fileName); + if(status == false) { + QMessageBox::critical(this,tr("Save Error"),m_bc.bc.error_message()); + } + return status; +} + +void MainWindow::about() +{ + QMessageBox::about(this, tr("About Zint"), + tr("

Zint Barcode Studio 2.3.2

" + "

A free barcode generator" + "

Visit the Zint Project Homepage for more information." + "

Copyright © 2010 Robin Stuart.
" + "Qt4 code by BogDan Vatra, MS Windows port by \"tgotic\".
" + "With thanks to Norbert Szabó, and Robert Elliott." + "

Released under the GNU General Public License ver. 3 or later.
" + "\"QR Code\" is a Registered Trademark of Denso Corp.
" + "\"Telepen\" is a Registered Trademark of SB Electronics." + "

Currently supported standards include:
" + "EN 797:1996, EN 798:1996, EN 12323:2005, ISO/IEC 15417:2007,
" + "ISO/IEC 15438:2006, ISO/IEC 16022:2006, ISO/IEC 16023:2000,
" + "ISO/IEC 16388:2007, ISO/IEC 18004:2006, ISO/IEC 24723:2006,
" + "ISO/IEC 24724:2006, ISO/IEC 24728:2006, ISO/IEC 24778:2008,
" + "ANSI-HIBC 2.3-2009, ANSI/AIM BC6-2000, ANSI/AIM BC12-1998,
" + "AIMD014 (v 1.63), USPS-B-3200
" + )); +} + +int MainWindow::open_data_dialog() +{ + int retval; + DataWindow dlg(txtData->text()); + retval = dlg.exec(); + if (dlg.Valid == 1) + txtData->setText(dlg.DataOutput); + return retval; +} + +int MainWindow::open_sequence_dialog() +{ + SequenceWindow dlg; + dlg.barcode = &m_bc; + return dlg.exec(); +} + +void MainWindow::on_fgcolor_clicked() +{ + m_fgcolor=QColorDialog::getColor(m_fgcolor,this); + update_preview(); +} + +void MainWindow::on_bgcolor_clicked() +{ + m_bgcolor=QColorDialog::getColor(m_bgcolor,this); + update_preview(); +} + +void MainWindow::change_print_scale() +{ + /* This value is only used when printing (saving) to file */ + m_bc.bc.setScale((float)spnScale->value()); +} + +void MainWindow::quit_now() +{ + close(); +} + +void MainWindow::change_options() +{ + QUiLoader uiload; + + if (tabMain->count()==3) + tabMain->removeTab(1); + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODE128) + { + QFile file(":/grpC128.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Code 128")); + chkComposite->setText(tr("Add 2D Component (GS1-128 only)")); + connect(m_optionWidget->findChild("radC128EAN"), SIGNAL(toggled( bool )), SLOT(composite_ean_check())); + connect(m_optionWidget->findChild("radC128Stand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC128CSup"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC128EAN"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC128HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + } + else + chkComposite->setText(tr("Add 2D Component")); + + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_PDF417) + { + QFile file(":/grpPDF417.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("PDF417")); + connect(m_optionWidget->findChild("codewords"), SIGNAL(valueChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbPDFECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbPDFCols"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radPDFTruncated"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radPDFStand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radPDFHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MICROPDF417) + { + QFile file(":/grpMicroPDF.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Micro PDF417")); + connect(m_optionWidget->findChild("cmbMPDFCols"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radMPDFStand"), SIGNAL(toggled( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_AZTEC) + { + QFile file(":/grpAztec.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Aztec Code")); + connect(m_optionWidget->findChild("radAztecAuto"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radAztecSize"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radAztecECC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbAztecSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbAztecECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radAztecStand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radAztecGS1"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radAztecHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MSI_PLESSEY) + { + QFile file(":/grpMSICheck.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("MSI Plessey")); + connect(m_optionWidget->findChild("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + } + + if((metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODE39) || + (metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_EXCODE39)) + { + QFile file(":/grpC39.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Code 39")); + connect(m_optionWidget->findChild("radC39Stand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC39Check"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC39HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_EXCODE39) + { + if(m_optionWidget->findChild("radC39HIBC")->isChecked() == true) + { + m_optionWidget->findChild("radC39HIBC")->setChecked(false); + m_optionWidget->findChild("radC39Stand")->setChecked(true); + } + m_optionWidget->findChild("radC39HIBC")->setEnabled(false); + } + else + m_optionWidget->findChild("radC39HIBC")->setEnabled(true); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODE16K) + { + QFile file(":/grpC16k.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Code 16K")); + connect(m_optionWidget->findChild("radC16kStand"), SIGNAL(toggled( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_DATAMATRIX) + { + QFile file(":/grpDM.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Data Matrix")); + connect(m_optionWidget->findChild("cmbDMMode"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbDMMode"), SIGNAL(currentIndexChanged( int )), SLOT(datamatrix_options())); + connect(m_optionWidget->findChild("radDM200Stand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radDM200GS1"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radDM200HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbDM200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbDMNon200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("chkDMRectangle"), SIGNAL(stateChanged( int )), SLOT(update_preview())); + datamatrix_options(); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_QRCODE) + { + QFile file(":/grpQR.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("QR Code")); + connect(m_optionWidget->findChild("radQRAuto"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radQRSize"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radQRECC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbQRSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbQRECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radQRStand"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radQRGS1"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radQRHIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MICROQR) + { + QFile file(":/grpMQR.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Micro QR Code")); + connect(m_optionWidget->findChild("radMQRAuto"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radMQRSize"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radMQRECC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbMQRSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbMQRECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_GRIDMATRIX) + { + QFile file(":/grpGrid.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Grid Matrix")); + connect(m_optionWidget->findChild("radGridAuto"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radGridSize"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radGridECC"), SIGNAL(clicked( bool )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbGridSize"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbGridECC"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_MAXICODE) + { + QFile file(":/grpMaxicode.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Maxicode")); + connect(m_optionWidget->findChild("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbMaxiMode"), SIGNAL(currentIndexChanged( int )), SLOT(maxi_primary())); + connect(m_optionWidget->findChild("txtMaxiPrimary"), SIGNAL(textChanged( const QString& )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CHANNEL) + { + QFile file(":/grpChannel.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Channel Code")); + connect(m_optionWidget->findChild("cmbChannel"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODEONE) + { + QFile file(":/grpCodeOne.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Code One")); + connect(m_optionWidget->findChild("cmbC1Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("radC1GS1"), SIGNAL(toggled( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CODE49) + { + QFile file(":/grpC49.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("Code 49")); + connect(m_optionWidget->findChild("radC49GS1"), SIGNAL(toggled( bool )), SLOT(update_preview())); + } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_RSS_EXPSTACK) + { + QFile file(":/grpDBExtend.ui"); + if (!file.open(QIODevice::ReadOnly)) + return; + m_optionWidget=uiload.load(&file); + file.close(); + tabMain->insertTab(1,m_optionWidget,tr("DataBar Stacked")); + connect(m_optionWidget->findChild("cmbCols"), SIGNAL(currentIndexChanged ( int )), SLOT(update_preview())); + } + + switch(metaObject()->enumerator(0).value(bstyle->currentIndex())) + { + case BARCODE_CODE128: + case BARCODE_EANX: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_RSS14: + case BARCODE_RSS_LTD: + case BARCODE_RSS_EXP: + case BARCODE_RSS14STACK: + case BARCODE_RSS14STACK_OMNI: + case BARCODE_RSS_EXPSTACK: + grpComposite->show(); + break; + default: + chkComposite->setChecked(false); + grpComposite->hide(); + break; + } + tabMain->setCurrentIndex(0); +} + +void MainWindow::composite_enable() +{ + if(chkComposite->isChecked() == true) + { + lblCompType->setEnabled(true); + cmbCompType->setEnabled(true); + lblComposite->setEnabled(true); + txtComposite->setEnabled(true); + if (metaObject()->enumerator(0).value(bstyle->currentIndex())==BARCODE_CODE128) + m_optionWidget->findChild("radC128EAN")->setChecked(true); + } + else + { + lblCompType->setEnabled(false); + cmbCompType->setEnabled(false); + lblComposite->setEnabled(false); + txtComposite->setEnabled(false); + } +} + +void MainWindow::composite_ean_check() +{ + if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_CODE128) + return; + if(!m_optionWidget->findChild("radC128EAN")->isChecked()) + chkComposite->setChecked(false); +} + + +void MainWindow::datamatrix_options() +{ + if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_DATAMATRIX) + return; + if(m_optionWidget->findChild("cmbDMMode")->currentIndex() == 0) + { + m_optionWidget->findChild("grpDMNon200")->hide(); + m_optionWidget->findChild("grpDM200")->show(); + } + else + { + m_optionWidget->findChild("grpDM200")->hide(); + m_optionWidget->findChild("grpDMNon200")->show(); + } +} + +void MainWindow::maxi_primary() +{ + if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_MAXICODE) + return; + if(m_optionWidget->findChild("cmbMaxiMode")->currentIndex() == 0) { + m_optionWidget->findChild("lblMaxiPrimary")->setEnabled(true); + m_optionWidget->findChild("txtMaxiPrimary")->setEnabled(true); + } else { + m_optionWidget->findChild("lblMaxiPrimary")->setEnabled(false); + m_optionWidget->findChild("txtMaxiPrimary")->setEnabled(false); + } +} + +void MainWindow::update_preview() +{ + QString error; + m_bc.ar=(Zint::QZint::AspectRatioMode)1; + if(chkComposite->isChecked() == true) { + m_bc.bc.setPrimaryMessage(txtData->text()); + m_bc.bc.setText(txtComposite->toPlainText()); + } else { + m_bc.bc.setText(txtData->text()); + /*m_bc.bc.setPrimaryMessage(txtComposite->text());*/ + } + m_bc.bc.setSecurityLevel(0); + m_bc.bc.setWidth(0); + m_bc.bc.setInputMode(UNICODE_MODE); + m_bc.bc.setHideText(FALSE); + if(chkHRTHide->isChecked() == false) { + m_bc.bc.setHideText(TRUE); + } + switch(metaObject()->enumerator(0).value(bstyle->currentIndex())) + { + case BARCODE_CODE128: + if(m_optionWidget->findChild("radC128Stand")->isChecked()) + m_bc.bc.setSymbol(BARCODE_CODE128); + + if(m_optionWidget->findChild("radC128CSup")->isChecked()) + m_bc.bc.setSymbol(BARCODE_CODE128B); + + if(m_optionWidget->findChild("radC128EAN")->isChecked()) + { + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_EAN128_CC); + else + m_bc.bc.setSymbol(BARCODE_EAN128); + } + + if(m_optionWidget->findChild("radC128HIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_128); + break; + + case BARCODE_EANX: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_EANX_CC); + else + m_bc.bc.setSymbol(BARCODE_EANX); + break; + + case BARCODE_UPCA: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_UPCA_CC); + else + m_bc.bc.setSymbol(BARCODE_UPCA); + break; + + case BARCODE_UPCE: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_UPCE_CC); + else + m_bc.bc.setSymbol(BARCODE_UPCE); + break; + + case BARCODE_RSS14: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS14_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS14); + break; + + case BARCODE_RSS_LTD: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS_LTD_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS_LTD); + break; + + case BARCODE_RSS_EXP: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS_EXP_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS_EXP); + break; + + case BARCODE_RSS14STACK: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS14STACK_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS14STACK); + break; + + case BARCODE_RSS14STACK_OMNI: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS14_OMNI_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS14STACK_OMNI); + break; + + case BARCODE_RSS_EXPSTACK: + if(chkComposite->isChecked()) + m_bc.bc.setSymbol(BARCODE_RSS_EXPSTACK_CC); + else + m_bc.bc.setSymbol(BARCODE_RSS_EXPSTACK); + + if(m_optionWidget->findChild("cmbCols")->currentIndex() != 0) + m_bc.bc.setWidth(m_optionWidget->findChild("cmbCols")->currentIndex()); + break; + + case BARCODE_PDF417: + m_bc.bc.setWidth(m_optionWidget->findChild("cmbPDFCols")->currentIndex()); + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbPDFECC")->currentIndex()-1); + m_bc.bc.setPdf417CodeWords(m_optionWidget->findChild("codewords")->value()); + if(m_optionWidget->findChild("radPDFStand")->isChecked()) + m_bc.bc.setSymbol(BARCODE_PDF417); + + if(m_optionWidget->findChild("radPDFTruncated")->isChecked()) + m_bc.bc.setSymbol(BARCODE_PDF417TRUNC); + + if(m_optionWidget->findChild("radPDFHIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_PDF); + break; + + case BARCODE_MICROPDF417: + m_bc.bc.setWidth(m_optionWidget->findChild("cmbMPDFCols")->currentIndex()); + if(m_optionWidget->findChild("radMPDFStand")->isChecked()) + m_bc.bc.setSymbol(BARCODE_MICROPDF417); + + if(m_optionWidget->findChild("radMPDFHIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_MICPDF); + break; + + case BARCODE_AZTEC: + m_bc.bc.setSymbol(BARCODE_AZTEC); + if(m_optionWidget->findChild("radAztecSize")->isChecked()) + m_bc.bc.setWidth(m_optionWidget->findChild("cmbAztecSize")->currentIndex() + 1); + + if(m_optionWidget->findChild("radAztecECC")->isChecked()) + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbAztecECC")->currentIndex() + 1); + + if(m_optionWidget->findChild("radAztecGS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + if(m_optionWidget->findChild("radAztecHIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_AZTEC); + break; + + case MSI_PLESSEY: + m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY); + m_bc.bc.setWidth(m_optionWidget->findChild("cmbMSICheck")->currentIndex()); + break; + + case BARCODE_CODE39: + if(m_optionWidget->findChild("radC39HIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_39); + else + { + m_bc.bc.setSymbol(BARCODE_CODE39); + if(m_optionWidget->findChild("radC39Check")->isChecked()) + m_bc.bc.setWidth(1); + } + break; + + case BARCODE_EXCODE39: + m_bc.bc.setSymbol(BARCODE_EXCODE39); + if(m_optionWidget->findChild("radC39Check")->isChecked()) + m_bc.bc.setWidth(1); + + break; + case BARCODE_CODE16K: + m_bc.bc.setSymbol(BARCODE_CODE16K); + if(m_optionWidget->findChild("radC16kStand")->isChecked()) + m_bc.bc.setInputMode(UNICODE_MODE); + else + m_bc.bc.setInputMode(GS1_MODE); + break; + + case BARCODE_CODABLOCKF: + if(m_optionWidget->findChild("radCodaGS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + + if(m_optionWidget->findChild("radCodaHIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_BLOCKF); + else + m_bc.bc.setSymbol(BARCODE_CODABLOCKF); + break; + + case BARCODE_DATAMATRIX: + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbDMMode")->currentIndex() + 1); + if(m_optionWidget->findChild("cmbDMMode")->currentIndex() == 0) + { /* ECC 200 */ + if(m_optionWidget->findChild("radDM200HIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_DM); + else + m_bc.bc.setSymbol(BARCODE_DATAMATRIX); + + if(m_optionWidget->findChild("radDM200GS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + + m_bc.bc.setWidth(m_optionWidget->findChild("cmbDM200Size")->currentIndex()); + if(m_optionWidget->findChild("chkDMRectangle")->isChecked()) + m_bc.bc.setOption3(DM_SQUARE); + else + m_bc.bc.setOption3(0); + } + else + { /* Not ECC 200 */ + m_bc.bc.setSymbol(BARCODE_DATAMATRIX); + m_bc.bc.setWidth(m_optionWidget->findChild("cmbDMNon200Size")->currentIndex()); + } + break; + + case BARCODE_QRCODE: + if(m_optionWidget->findChild("radQRHIBC")->isChecked()) + m_bc.bc.setSymbol(BARCODE_HIBC_QR); + else + m_bc.bc.setSymbol(BARCODE_QRCODE); + + if(m_optionWidget->findChild("radQRGS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + + if(m_optionWidget->findChild("radQRSize")->isChecked()) + m_bc.bc.setWidth(m_optionWidget->findChild("cmbQRSize")->currentIndex() + 1); + + if(m_optionWidget->findChild("radQRECC")->isChecked()) + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbQRECC")->currentIndex() + 1); + break; + + case BARCODE_MICROQR: + m_bc.bc.setSymbol(BARCODE_MICROQR); + if(m_optionWidget->findChild("radMQRSize")->isChecked()) + m_bc.bc.setWidth(m_optionWidget->findChild("cmbMQRSize")->currentIndex()); + + if(m_optionWidget->findChild("radMQRECC")->isChecked()) + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbMQRECC")->currentIndex() + 1); + break; + + case BARCODE_GRIDMATRIX: + m_bc.bc.setSymbol(BARCODE_GRIDMATRIX); + if(m_optionWidget->findChild("radGridSize")->isChecked()) + m_bc.bc.setWidth(m_optionWidget->findChild("cmbGridSize")->currentIndex() + 1); + + if(m_optionWidget->findChild("radGridECC")->isChecked()) + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbGridECC")->currentIndex() + 1); + break; + + case BARCODE_MAXICODE: + m_bc.bc.setSymbol(BARCODE_MAXICODE); + if(m_optionWidget->findChild("cmbMaxiMode")->currentIndex() == 0) + { + m_bc.bc.setSecurityLevel(2); + m_bc.bc.setPrimaryMessage(m_optionWidget->findChild("txtMaxiPrimary")->text()); + } + else + m_bc.bc.setSecurityLevel(m_optionWidget->findChild("cmbMaxiMode")->currentIndex() + 3); + break; + + case BARCODE_CHANNEL: + m_bc.bc.setSymbol(BARCODE_CHANNEL); + if(m_optionWidget->findChild("cmbChannel")->currentIndex() == 0) + m_bc.bc.setWidth(0); + else + m_bc.bc.setWidth(m_optionWidget->findChild("cmbChannel")->currentIndex() + 2); + break; + + case BARCODE_CODEONE: + m_bc.bc.setSymbol(BARCODE_CODEONE); + if(m_optionWidget->findChild("radC1GS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + m_bc.bc.setWidth(m_optionWidget->findChild("cmbC1Size")->currentIndex()); + break; + + case BARCODE_CODE49: + m_bc.bc.setSymbol(BARCODE_CODE49); + if(m_optionWidget->findChild("radC49GS1")->isChecked()) + m_bc.bc.setInputMode(GS1_MODE); + break; + + default: + m_bc.bc.setSymbol(metaObject()->enumerator(0).value(bstyle->currentIndex())); + break; + } + + if(chkComposite->isChecked()) + m_bc.bc.setSecurityLevel(cmbCompType->currentIndex()); + + m_bc.bc.setBorderType((Zint::QZint::BorderType)(btype->currentIndex()*2)); + m_bc.bc.setBorderWidth(bwidth->value()); + m_bc.bc.setHeight(heightb->value()); + m_bc.bc.setWhitespace(spnWhitespace->value()); + m_bc.bc.setFgColor(m_fgcolor); + m_bc.bc.setBgColor(m_bgcolor); + m_bc.update(); + view->scene()->update(); +} + +void +MainWindow::zoomIn(void) +{ + scaleSlider->setValue(scaleSlider->value() + scaleSlider->singleStep()); +} +void +MainWindow::zoomOut(void) +{ + scaleSlider->setValue(scaleSlider->value() - scaleSlider->singleStep()); +} +void +MainWindow::rotateLeft(void) +{ + rotateSlider->setValue(rotateSlider->value() - rotateSlider->singleStep()); +} +void +MainWindow::rotateRight(void) +{ + rotateSlider->setValue(rotateSlider->value() + rotateSlider->singleStep()); +} diff --git a/frontend_qt4/mainwindow.h b/frontend_qt4/mainwindow.h new file mode 100644 index 00000000..8c6078cc --- /dev/null +++ b/frontend_qt4/mainwindow.h @@ -0,0 +1,148 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * Copyright (C) 2009 by Robin Stuart * + * * + * 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, see . * + ***************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +#include "ui_mainWindow.h" +#include "barcodeitem.h" + +class QAction; +class QActionGroup; +class QLabel; +class QMenu; + +class MainWindow : public QWidget, private Ui::mainWindow +{ + Q_OBJECT + + Q_ENUMS(BarcodeTypes) + +public: + enum BarcodeTypes + { + AUSREDIRECT =68, + AUSREPLY =66, + AUSROUTE =67, + AUSPOST =63, + AZTEC =92, + AZRUNE =128, + CHANNEL =140, + CODABAR =18, + CODE11 =1, + CODE128 =20, + CODE16K =23, + C25LOGIC =6, + C25IATA =4, + C25IND =7, + C25INTER =3, + C25MATRIX =2, + CODE32 =129, + CODE39 =8, + EXCODE39 =9, + CODE49 =24, + CODE93 =25, + CODE_ONE =141, + RSS14 =29, + RSS_EXP =31, + RSS_EXPSTACK =81, + RSS_LTD =30, + RSS14STACK =79, + RSS14STACK_OMNI =80, + DATAMATRIX =71, + DPIDENT =22, + DPLEIT =21, + KIX =90, + EAN14 =72, + EANX =13, + FIM =49, + FLAT =28, + GRIDMATRIX =142, + ITF14 =89, + ISBNX =69, + JAPANPOST =76, + KOREAPOST =77, + LOGMARS =50, + MAXICODE =57, + MICROPDF417 =84, + MICROQR =97, + MSI_PLESSEY =47, + NVE18 =75, + PDF417 =55, + PHARMA =51, + PHARMA_TWO =53, + PZN =52, + PLANET =82, + POSTNET =40, + QRCODE =58, + RM4SCC =70, + TELEPEN =32, + TELEPEN_NUM =87, + PLESSEY =86, + UPCA =34, + UPCE =37, + ONECODE =85 + }; + +public: + MainWindow(QWidget* parent = 0, Qt::WFlags fl = 0); + ~MainWindow(); + + +public slots: + void update_preview(); + void change_options(); + void on_fgcolor_clicked(); + void on_bgcolor_clicked(); + void composite_enable(); + void composite_ean_check(); + void datamatrix_options(); + void maxi_primary(); + void change_print_scale(); + void scaleRotate(); + void zoomIn(void); + void zoomOut(void); + void rotateLeft(void); + void rotateRight(void); + +private slots: + bool save(); + void about(); + void quit_now(); + void reset_view(); + int open_data_dialog(); + int open_sequence_dialog(); + +private: +/* void createActions(); + void createMenus(); */ + + QColor m_fgcolor,m_bgcolor; + BarcodeItem m_bc; + QWidget *m_optionWidget; +/* QMenu *fileMenu; + QMenu *helpMenu; + QAction *saveAct; + QAction *aboutQtAct; */ +}; + +#endif + + diff --git a/frontend_qt4/qtZint.sln b/frontend_qt4/qtZint.sln new file mode 100644 index 00000000..05c99e7e --- /dev/null +++ b/frontend_qt4/qtZint.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtZint", "qtZint.vcproj", "{6B8BFC0E-48F8-3D3B-BC6F-9EBEC23A8BC1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B8BFC0E-48F8-3D3B-BC6F-9EBEC23A8BC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {6B8BFC0E-48F8-3D3B-BC6F-9EBEC23A8BC1}.Debug|Win32.Build.0 = Debug|Win32 + {6B8BFC0E-48F8-3D3B-BC6F-9EBEC23A8BC1}.Release|Win32.ActiveCfg = Release|Win32 + {6B8BFC0E-48F8-3D3B-BC6F-9EBEC23A8BC1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/frontend_qt4/qtZint.vcproj b/frontend_qt4/qtZint.vcproj new file mode 100644 index 00000000..ffb94b25 --- /dev/null +++ b/frontend_qt4/qtZint.vcproj @@ -0,0 +1,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend_qt4/res/.directory b/frontend_qt4/res/.directory new file mode 100644 index 00000000..1450a1d7 --- /dev/null +++ b/frontend_qt4/res/.directory @@ -0,0 +1,3 @@ +[Dolphin] +ShowPreview=true +Timestamp=2010,5,29,7,59,30 diff --git a/frontend_qt4/res/qtZint.rc b/frontend_qt4/res/qtZint.rc new file mode 100644 index 00000000..5a23c6d8 --- /dev/null +++ b/frontend_qt4/res/qtZint.rc @@ -0,0 +1,85 @@ +#define WIN32_LEAN_AND_MEAN + +#include + +#include + + + +#ifdef GCC_WINDRES + +VS_VERSION_INFO VERSIONINFO + +#else + +VS_VERSION_INFO VERSIONINFO + +#endif + + FILEVERSION 2,3,0,0 + + PRODUCTVERSION 2,3,0,0 + + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + +#ifdef _DEBUG + + FILEFLAGS VS_FF_DEBUG + +#else + + FILEFLAGS 0 + +#endif + + FILEOS VOS_NT_WINDOWS32 + + FILETYPE VFT_APP + + FILESUBTYPE VFT2_UNKNOWN + +BEGIN + + BLOCK "StringFileInfo" + + BEGIN + + BLOCK "000904b0" + + BEGIN + + VALUE "CompanyName", "Robin Stuart & BogDan Vatra" + + VALUE "FileDescription", "qtZint barcode generator" + + VALUE "FileVersion", "2.3.2.0" + + VALUE "InternalName", "qtZint" + + VALUE "LegalCopyright", "Copyright 2010 Robin Stuart & BogDan Vatra" + + VALUE "License", "GNU General Public License version 3" + + VALUE "OriginalFilename", "qtZint" + + VALUE "ProductName", "Zint Barcode Studio" + + VALUE "ProductVersion", "2.3.2.0" + + VALUE "WWW", "http://www.zint.org.uk" + + END + + END + + BLOCK "VarFileInfo" + + BEGIN + + VALUE "Translation", 0x9, 1200 + + END + +END + +100 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "zint.ico" \ No newline at end of file diff --git a/frontend_qt4/res/zint.ico b/frontend_qt4/res/zint.ico new file mode 100644 index 0000000000000000000000000000000000000000..c952376a964a7030ea5eb5a58ecdad7cfd127900 GIT binary patch literal 25842 zcmeHP2|!cF);>1`2rg`*_)CSjp{-~@t3I_tuqs-uLVr=83!v7uwZN}c6qQ)(@~jFx zTesHM*1Gf+SroO3O4R38eni|*5y1^yA5mlxgn4Ifa+8}7LQoLe=ICT*&N<)N?qqT& zZ~;Y_TmGkN507qLP0Eq!HI5Yxq z6?1qo?CJo}=N%4@bHv>q!QsU)T?nu$2%r<<5e8ChG!DZg1Hk_vlPNoV#UVBs$mMbr z5cWS1LPyx}A7#;(>Ijv1#DZ#huFwjBkebf5lc2%TC^@4xbdE0yP#WgVl?;ts2|@*x zzRHM=${s3eg~l4?+|Zu&%wxRL96>yK{d)7_(Kn>NWVpl(Hmbw5_q>R#Wy=V;t;hwN zO^&U|Qh}|cWlOV)xBg~ENCm@hhU`+`be+3n3&KXApm|+0F&bZ=B5FxRDj(^ z0v5Pu8t`G|jt_yWWiBEA^$FA!hG z!%Nx#`1S$_83qtF86bW>Kw2b#Vh7lfMDQR-!H=AQP;wEX$qh&#_aL1vTrPeIZa%&( z5#JW^Ziw%Rcq!sPK>Rqwha!Fj;;_o2-0pjx!U&O;pTrqub zOn)4vKL^uai|PM@>7T&2$pt$gS3Q7a`2o2b3glrlzTp#q6s4=b1)U)tdO{lR@Cq0L#BMAQj}Rb!%YlS` z2PAqAkc2Zp(lyslf}aS!hzWsVh@XV`FvPD#{LhHri}<66KaF_w8GQrs_YkjHKW-p_ zp=eYc#%M$EM2pHoecfzzz=riGBo*hZ0DOCU7Hxz@u~xUW9mBf#!&JLVO#hv1(BAO+G651=p`BjRNN^e8X4S}eGU*$x)tjvk^;SJ;u5b0a zRHLr-h3XO-7mq~^^+BzVyP7ei(boVN#sHEBP$5{35MzC2#$w6U#0Sd18D$N>uY792B5w)4WeaUv9+9#i5;56E&*IGeG3jy3&~AqV6Z5TWY5@E)1Y zT>wf{{Y%>0U_OBQw3jQK0XGstO1zXkA#!$3NDk&ny&39jyAISJzuxqmD#j+oR^2(3 z1zP(8ID`PSib7yKehGvJ9XC8D_QP}HXgnw4J+A4TYC5Ny&Z(wzDsCw}Vhj*fGazQ~ zz8i#`myhm{jZc@!o7almz&V7g4|Pe$JlD#hN?oDGZy zLlwE6Z-DZ&h_zTb6^%}H3U5xX^rZil#;aeViLb8Znwq`Jh~72GFbRW=>Ts3i8zfZTJq~2QrG-Jx7bKFsQ#QVHsxs~VI0JMjC z3?B8shQ25bvh&JNR)H!hiPhpJ*jENn9-k`Dd2oG0dWNOVVlw`WtPQ}I*iHrExl^HR zx|o0X4)Mc;|8Lh+0ISR)1H4CuU4N2w?5nqC{Ez(B z!%d%#y3=;B)Y~;@f-tgshRkurzz;7hwal_h3$PEaV0urLD%v~$l;lyAbGt*v_>QM# zVMS5BSK3}WVbP)et48iVfP*r0_Pn`YgT&U!Nb@CNe?&pW?k+#Lzd{eZ#3-k z0kH=o`?nD6o5A2={7Fn_=v$C7>d7}|UGGj`+`H?+iKAg^K}uqggM8WJRLP1Cy&RyW ziy9jf2(j<38wH<@$bUC-+TQC+nIAkheVG&wQVRk6!wTBFLe$ld1nyQh&425@rDu0W z_RXHJ;azXoA%M z6uZLDV(?(Z=FCbfcv}Q_<4Y`e7kcgoskOkiOJF#(TnPhGGMvGpEu=r&XDM4Ek|r*E z!UT!yQ7j5P^z7#I-%m~L3=!oS*`LIXl?cH6Xwi$fFNs-6!LP}e0`>(6p^->>nugp) zr|)oeQ{aBj@RMcPrA6n~NFoaVbIqyZ_KCnN0U2#20f(o5-!J^ip~b<$lI!UI~ZEFV>-2m)zRQ! zFDvYIX~i{1pKps7WT%{57JO%5i@v3kR=BK-w28=Gs3>+cCt%q;_6O` z0m)feS-Z>2%YVw46CR#)F!atT+Yu>26(J>|1>26e?2jcr1s{N5_kkrAqZW2M)q7<5 zpl_!fX?l6$oZvf!`$Y1{V$bOl$bsBuj7TK!&`fqnn6prr^G_@31VMT7q=UlAxho+ z7_Q|7EeVw%QK#&n@BngMuiv{e%x4^UN+{}L(KT&*5@}zWO=15 zwsMLGk$eX7L{j&|@VqT7@y`OGxMct=u#?IE^%)3kn@He@NE+nd3mDOIM_ItBR!XNgNUxk2fvv493PW08D+>x^ zI=O;C46_9Bxy+b@1=lv5^p;a@&npnd9BCR>G?QM7&COJ*pA3gDZkcc02r<3cNGBnV zO=Z=ZHn1&Imi9g?pOO>jkG~So&x&T8D3T90Fu>fxQ!gvV%kn=A&TxKme2-<$v89%& zd#9xhpHTep@~_)Ej`;p9VK0}v(<2<2`@aN3Y_E*5Y1wg8lV=?5e#AdKv2lvCtW9$I zP6=~=2=y)np%l*H?}*{1Nvr8+5fr*O;?cO?d6Hp|{11i~|L23nOY*vn?+<8Z#Nwih zTjC-LoOT`^G0{KSp~uzp->$H6>1rL;`iFxHo-SK&IdI;gFPN~Ww+B9w2W%L+F~U91 zO5O?G#XU}5vtddFDd>5#TdvD$Tq9F(VI+e{+9}04YSCiGR_43DwYcmhmiI@uzS5!> z7+HU_#Xr7(IWHn7ZI4Y0+1d=r!bY2$FLa74ewp{%ZV+PNS2n@(_8^EqC*0Z*O?*zP zD1(^2u@4-*Zhii6_RgfFq;X|sW$8XkK1mCC@KeFTr2n6{diu683m+H!cHjE<<`E9z z7rxH_Cb)5MFU5<;yTR?zw)3sy0zZDbz`4uBEB`vQf896XPE!ZB?l^nSFQsd`ei+j2 z%Bh{5{r8Uz-h7*QH+dlm`lM{!PuJrD{gn%4bri-WZV&C+;|ICON-o-NBkz4~TK-36 zXF|ekL+(5?bH9szmYyFvvaImecNW1+($nb@rXZb!nd7ICYS7}d^1x4H_X`wR51!=S zdhGY4@JPIW`K+G1hJX-17p3%5Q8jS8Q4-f<^jK!h%YgC~dr$AnC_XNP>&MrS+4N0t zV8^`8kwO?WkW*)ID9xJMu8DlxwfvcJ`OB;zahVgjEQSN-Fvv$sQ_GdwCud~KT6j4M zf=24m62Hhl(ftFTf|Ss+P0iud&XNONu=9a)_F!)(+bfg}5azfsVmn6G#C2VWV+%MV z<$uoC;)km4ErdbS3EPD^Gkw6>3Su18cM*s{eo$<4+1ZzAxgYQS{KUF7>jKOU&o9`K z@hrX1qCS`J-k4YD6`U5Dxn|G35q-Yjadyzfr;f`aU2fzLIbFIUvd7!wE8dgLK3(AT z_M({Bq^4KM&v`G`Ij0pI&y3C37gBLxS%GAI){ReX6s3ia?&soCSQgmV~o6 z2|(G*7!9A*p>vK$dk_#a0Z)gH`8)>Ybk6dyr+z4pHaZqi8KdmE7^n?~$D?Cx`1_7r zT)`6)^DBSo^@Gpd{GsEg>)Kdqpzi@=!)NtWIT(5` z69&xKR*kN{Js2UcL^aBRDx(*DIq0=xtgcE=pWW(`((Bg{Q%_8W)b-_CrT#1CQKdb7 z0)G6BpqW0EN<2P>j;kXbeViJk>da}$(GveUYsspb)B?s}0@S{-R12{f>q_6+Gn9u> zcKPw+^P4rsyhg1I#m>ptoDBuVkKfo>UIoL&po7J!QB-9fh~}?eE=_)}U^$i`R9_&QVD>SBlfCYlztxpRUz)SO;_691Zzobq&SLm*Ml#hHTYADn^^+ zhgszqtu@s6=`-h5#?2Qr;2ij2Ryj7sZ}gh3sbZBi=L`OX^=J1mRbKTv=GVEZv7Y)@ zrP?6*ruggkvY6^`s{iX$;Lo;x@NZhZPC4E1Vmc^}QUb^Iu>43l~>?@3kiXZ@2<@;pv*==nZ?X^fR6Y=^u+z z*Y8V%^;h}lbn3F#TmQehe_9k(4fyXB?mF;g`sAFRF}>dU^O>qRI9q%XJJyw}=3I;% z&QM>;CZEBx&u43mtI|>NtE-WgE!{~~w)uM1>G0$@)JuGGT4U7a;@9HyCpFa38vwPT zk7{UJp9z-7vs0CS%4gRN--r&5FVbhXlAO=bu|@q=Mcn%3dcGdV8K9{aY?#L&bRQYeRF@CH(s^q`HPdvA!v`I$eEoT|76hY0ueK z;jpU_sbfbJ&8McM#?v?u%(qe1TuX;vKOUa7OJ#f>om1lRaHzaD)bXzuZ=hD3O|95; z{cw0aG0-@SA$@TfgX476^+pCiW~0Yk4ji7F*R-!KJZI + + images/zoomout.png + images/rotateleft.png + images/rotateright.png + images/zoomin.png + grpAztec.ui + grpC39.ui + grpDM.ui + grpMSICheck.ui + grpC128.ui + grpChannel.ui + grpMicroPDF.ui + grpMaxicode.ui + grpPDF417.ui + grpC16k.ui + grpCodablock.ui + grpMQR.ui + grpQR.ui + grpCodeOne.ui + grpC49.ui + grpGrid.ui + grpDBExtend.ui + images/zint.png + + diff --git a/frontend_qt4/sequencewindow.cpp b/frontend_qt4/sequencewindow.cpp new file mode 100644 index 00000000..f5076b84 --- /dev/null +++ b/frontend_qt4/sequencewindow.cpp @@ -0,0 +1,196 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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 +#include +#include +#include +#include + +#include "sequencewindow.h" +#include "exportwindow.h" +#include + +SequenceWindow::SequenceWindow() +{ + setupUi(this); + QValidator *intvalid = new QIntValidator(this); + + linStartVal->setValidator(intvalid); + linEndVal->setValidator(intvalid); + linIncVal->setValidator(intvalid); + connect(btnClose, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(reset_preview())); + connect(btnCreate, SIGNAL( clicked( bool )), SLOT(create_sequence())); + connect(txtPreview, SIGNAL( textChanged()), SLOT(check_generate())); + connect(btnImport, SIGNAL( clicked( bool )), SLOT(import())); + connect(btnExport, SIGNAL( clicked( bool )), SLOT(generate_sequence())); +} + +SequenceWindow::~SequenceWindow() +{ +} + +void SequenceWindow::quit_now() +{ + close(); +} + +void SequenceWindow::reset_preview() +{ + txtPreview->clear(); +} + +QString SequenceWindow::apply_format(QString raw_number) +{ + QString adjusted, reversed; + QString format; + int format_len, input_len, i, inpos; + char format_char; + QChar format_qchar; + + format = linFormat->text(); + input_len = raw_number.length(); + format_len = format.length(); + + inpos = input_len; + + for(i = format_len; i > 0; i--) { + format_qchar = format[i - 1]; + format_char = format_qchar.toAscii(); + switch(format_char) { + case '#': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += ' '; + } + break; + case '$': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += '0'; + } + break; + case '*': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += '*'; + } + break; + default: + adjusted += format_char; + break; + } + } + + for(i = format_len; i > 0; i--) { + reversed += adjusted[i - 1]; + } + + return reversed; +} + +void SequenceWindow::create_sequence() +{ + QString startval, endval, incval, part, outputtext; + int start, stop, step, i; + bool ok; + + startval = linStartVal->text(); + endval = linEndVal->text(); + incval = linIncVal->text(); + start = startval.toInt(&ok, 10); + stop = endval.toInt(&ok, 10); + step = incval.toInt(&ok, 10); + + if((stop <= start) || (step <= 0)) { + QMessageBox::critical(this, tr("Sequence Error"), tr("One or more of the input values is incorrect.")); + return; + } + + for(i = start; i <= stop; i += step) { + part = apply_format(QString::number(i, 10)); + part += '\n'; + outputtext += part; + } + + txtPreview->setPlainText(outputtext); +} + +void SequenceWindow::check_generate() +{ + QString preview_copy; + + preview_copy = txtPreview->toPlainText(); + if(preview_copy.isEmpty()) { + btnExport->setEnabled(false); + } else { + btnExport->setEnabled(true); + } +} + +void SequenceWindow::import() +{ + //QString fileName; + //QFileDialog fdialog; + QFile file; + QString selectedFilter; + + //fdialog.setFileMode(QFileDialog::ExistingFile); + + //if(fdialog.exec()) { + // fileName = fdialog.selectedFiles().at(0); + //} else { + // return; + //} + + QString fileName = QFileDialog::getOpenFileName(this, + tr("Import File"), + "./", + tr("All Files (*);;Text Files (*.txt)")); + if (fileName.isEmpty()) + return; + + file.setFileName(fileName); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); + return; + } + + QByteArray outstream = file.readAll(); + + txtPreview->setPlainText(QString(outstream)); + file.close(); +} + +void SequenceWindow::generate_sequence() +{ + int returnval; + + ExportWindow dlg; + dlg.barcode = barcode; + dlg.output_data = txtPreview->toPlainText(); + returnval = dlg.exec(); +} diff --git a/frontend_qt4/sequencewindow.h b/frontend_qt4/sequencewindow.h new file mode 100644 index 00000000..0aa34469 --- /dev/null +++ b/frontend_qt4/sequencewindow.h @@ -0,0 +1,47 @@ +/* + Zint Barcode Generator - the open source barcode generator + Copyright (C) 2009 Robin Stuart + + 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. +*/ + +#ifndef SEQUENCEWINDOW_H +#define SEQUENCEWINDOW_H + +#include "ui_extSequence.h" +#include "barcodeitem.h" + +class SequenceWindow : public QDialog, private Ui::SequenceDialog +{ + Q_OBJECT + +public: + SequenceWindow(); + ~SequenceWindow(); + BarcodeItem *barcode; + +private: + QString apply_format(QString raw_number); + +private slots: + void quit_now(); + void reset_preview(); + void create_sequence(); + void check_generate(); + void import(); + void generate_sequence(); +}; + +#endif \ No newline at end of file diff --git a/gpl-3.0.txt b/gpl-3.0.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/readme b/readme new file mode 100644 index 00000000..e07cc7b3 --- /dev/null +++ b/readme @@ -0,0 +1,158 @@ +Zint and libzint 2.3.2 +---------------------- +Zint is a suite of programs to allow easy encoding of data in any of the wide range of public domain +barcode standards and to allow integration of this capability into your own programs. This version +of Zint is able to encode data in the following formats: + +Code 11, Standard Code 2 of 5, IATA Code 2 of 5, Industrial Code 2 of 5, Interleaved Code 2 of 5, +Code 2 of 5 Data Logic, ITF-14, Deutche Post Leitcode, Deutche Post Identcode, UPC-A, UPC-E, EAN-2, +EAN-5, EAN-8, EAN-13, UK Plessey, MSI Plessey, Telepen Alpha, Telepen Numeric, Code 39, +Extended Code 39, Code 93, PZN, Code 23, LOGMARS, Codabar, Pharmacode, Code 128, EAN-128, NVE-18, +Code 16k, PDF417, MicroPDF417, Two-Track Pharmacode, PostNet, PLANET, Australia Post 4-State Symbols, +RM4SCC, USPS OneCode, GS1 DataBar, DataBar-14, DataBar Limited, DataBar Extended, DataBar Stacked, +Composite Symbology, Data Matrix, QR Code, Maxicode, Aztec Code, EAN-13, Micro QR, +Korea Post Barcode, HIBC Code 128, HIBC Code 39, HIBC Data Matrix, HIBC PDF417, HIBC MicroPDF417, +HIBC QR Code, HIBC Codablock-F, HIBC Aztec Code, Japanese Postal Code, Code 49, Channel Code, Code One, +Grid Matrix, FIM and Flattermarken. + + ****************************************************************************** + * PLEASE NOTE: This is just a simple guide to getting Zint working. * + * More complete documentation is available from the project website: * + * >>> http://www.zint.org.uk <<< * + ****************************************************************************** + +PROJECT STATUS +-------------- +Version 2.3.0: +This release features a complete rebuild of QR Code and Micro QR Code functionality which now: + +* Automatically detects and adjusts to Japanese characters +* Supports GS1 encoding +* Does not require the qrencode library. + +Also new in this release is Grid Matrix support which similarly supports Chinese character encoding. + +Version 2.3.1: +Correction of some minor bugs in Code 128 and Data Matrix, addition of --notext option to CLI and +better operation of --scale option which now scales human readable text and MaxiCode. + +SPECIAL NOTE: Codablock-F has now been REMOVED from this project because of problems implimenting +this standard. For full details see the project website. + +Version 2.3.2: +More bug corrections including important corrections to RSS Expanded, Maxicode and ISBN. + +COMPILING THE CODE +------------------ +The CMake Method: +The easiest way to configure compilation is to take advantage of the CMake utilities. You will +need to install CMake first. If no Qt libraries are installed then CMake will not attempt to +build the Zint Barcode Studio GUI. Similarly if libpng is not detected then CMake will not attempt +to compile PNG image support. This method is recommened in most cases, the notable exception +being MinGW. + +Once CMake is installed follow these steps: + + cd build + cmake .. + make + make install + +The command line program can be accessed by typing + + zint {options} -d {data} + +Notice that the data needs to be entered after all other options. Any options given after the +data will be ignored. The GUI can be accessed by typing + + zint-qt + +The MakeFile Method: +MakeFiles are provided for some systems although this method is now depreciated. This method compiles +and installs the library and CLI only. If you have installed Zint using this method before please +note that the binaries will now install to a different location than version 2.3.0 or earlier +(/usr/bin rather than /usr/local/bin and /usr/lib rather than /usr/local/lib). This makes +installation easier on Red Hat based systems (RHEL, CentOS, Fedora etc.) and on BSD-like systems +(FreeBSD, OpenBSD etc.) and is more correctly in line with the LSB. YOU WILL NEED TO UNINSTALL +PREVIOUS VERSIONS OF ZINT BEFORE USING THIS METHOD. + +To compile using this method simply run: + + make + make install + +If compiling on MinGW substitute the Makefile.mingw files for the default Makefiles in both the +/frontend and /backend folders. + +MS Windows: +Compiling on Cygwin and MinGW are covered above. Compiling with MS Visual Studio is more involved! +Full instructions are currently not ready for publication but will be placed on the project website +as soon as possible. + +Mac OSX: +Efforts are currently under way to ease compiling on OSX using the CMake method. It may be possible +to compile Zint using methods similar to those given above, but this has not been thoroughly tested +yet. If you have any success with compiling Zint on OSX then please get in touch. An install binary +for OSX is also in development. + +THINGS TO DO +------------ +If you are interested in improving this package then here are a few ideas. + +Backend +------- + * Create filters for more output file formats. + * Add ECI character support to allow encoding in more languages than are covered + by the Latin-1 character set. + * The code was developed to be easy to understand rather than efficient so may benefit + from some memory optimisation for embedded systems. + +GUI Frontend +------------ + * Allow copying of generated barcodes to the clipboard with a "Copy" button. + * Allow dragging and dropping to external apps. + +Packaging +--------- + Binary packages are needed for distribution in the following formats + * RPMs for various Linux distros (.spec file now available thanks to Radist) + * Install binaries for Mac OSX + +Translations +------------ + Documentation is currently only in English. If you have the knowledge and the + time please consider translating into other languages. + +Research +-------- + The following standards would be welcomed in Zint but the full documentation has + not yet been found. + * DPD Code + * Italian Postal Code + + +CONTACT ME +---------- +The home of libzint is: + + http://www.sourceforge.net/projects/zint + +and the home for Zint documentation is: + + http://www.zint.org.uk + +For feature requests or bug reports please join the mailing list at + + https://lists.sourceforge.net/lists/listinfo/zint-barcode + +or send an e-mail to + + zint-barcode@lists.sourceforge.net + +Thanks for your interest in libzint. +Happy encoding. + +Robin. + + + diff --git a/readme-cmake b/readme-cmake new file mode 100644 index 00000000..801b076d --- /dev/null +++ b/readme-cmake @@ -0,0 +1,6 @@ +how to : +mkdir build +cd build +cmake .. +make [-j nr_proc+1] +make install diff --git a/win32/libzint.vcproj b/win32/libzint.vcproj new file mode 100644 index 00000000..40f81839 --- /dev/null +++ b/win32/libzint.vcproj @@ -0,0 +1,517 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/win32/test.bat b/win32/test.bat new file mode 100755 index 00000000..1dec0ae9 --- /dev/null +++ b/win32/test.bat @@ -0,0 +1,837 @@ +@echo off +echo testing Code 11 + +zint -o bar01.png -b 1 --height=50 --border=10 -d 87654321 + +zint -o bar01.eps -b 1 --height=50 --border=10 -d 87654321 + +zint -o bar01.svg -b 1 --height=50 --border=10 -d 87654321 + +echo testing Code 2 of 5 Standard + +zint -o bar02.png -b 2 --height=50 --border=10 -d 87654321 + +zint -o bar02.eps -b 2 --height=50 --border=10 -d 87654321 + +zint -o bar02.svg -b 2 --height=50 --border=10 -d 87654321 + +echo testing Interleaved 2 of 5 + +zint -o bar03.png -b 3 --height=50 --border=10 -d 87654321 + +zint -o bar03.eps -b 3 --height=50 --border=10 -d 87654321 + +zint -o bar03.svg -b 3 --height=50 --border=10 -d 87654321 + +echo testing Code 2 of 5 IATA + +zint -o bar04.png -b 4 --height=50 --border=10 -d 87654321 + +zint -o bar04.eps -b 4 --height=50 --border=10 -d 87654321 + +zint -o bar04.svg -b 4 --height=50 --border=10 -d 87654321 + +echo testing Code 2 of 5 Data Logic + +zint -o bar06.png -b 6 --height=50 --border=10 -d 87654321 + +zint -o bar06.eps -b 6 --height=50 --border=10 -d 87654321 + +zint -o bar06.svg -b 6 --height=50 --border=10 -d 87654321 + +echo testing Code 2 of 5 Industrial + +zint -o bar07.png -b 7 --height=50 --border=10 -d 87654321 + +zint -o bar07.eps -b 7 --height=50 --border=10 -d 87654321 + +zint -o bar07.svg -b 7 --height=50 --border=10 -d 87654321 + +echo testing Code 39 + +zint -o bar08.png -b 8 --height=50 --border=10 -d CODE39 +zint -o bar08.eps -b 8 --height=50 --border=10 -d CODE39 + +zint -o bar08.svg -b 8 --height=50 --border=10 -d CODE39 + +echo testing Extended Code 39 + +zint -o bar09.png -b 9 --height=50 --border=10 -d "Code 39e" + +zint -o bar09.eps -b 9 --height=50 --border=10 -d "Code 39e" + +zint -o bar09.svg -b 9 --height=50 --border=10 -d "Code 39e" + +echo testing EAN8 + +zint -o bar10.png -b 13 --height=50 --border=10 -d 7654321 + +zint -o bar10.eps -b 13 --height=50 --border=10 -d 7654321 + +zint -o bar10.svg -b 13 --height=50 --border=10 -d 7654321 + +echo testing EAN8 - 2 digits add on + +zint -o bar11.png -b 13 --height=50 --border=10 -d 7654321+21 + +zint -o bar11.eps -b 13 --height=50 --border=10 -d 7654321+21 + +zint -o bar11.svg -b 13 --height=50 --border=10 -d 7654321+21 + +echo testing EAN8 - 5 digits add-on + +zint -o bar12.png -b 13 --height=50 --border=10 -d 7654321+54321 + +zint -o bar12.eps -b 13 --height=50 --border=10 -d 7654321+54321 + +zint -o bar12.svg -b 13 --height=50 --border=10 -d 7654321+54321 + +echo testing EAN13 + +zint -o bar13.png -b 13 --height=50 --border=10 -d 210987654321 + +zint -o bar13.eps -b 13 --height=50 --border=10 -d 210987654321 + +zint -o bar13.svg -b 13 --height=50 --border=10 -d 210987654321 + +echo testing EAN13 - 2 digits add-on + +zint -o bar14.png -b 13 --height=50 --border=10 -d 210987654321+21 + +zint -o bar14.eps -b 13 --height=50 --border=10 -d 210987654321+21 + +zint -o bar14.svg -b 13 --height=50 --border=10 -d 210987654321+21 + +echo testing EAN13 - 5 digits add-on + +zint -o bar15.png -b 13 --height=50 --border=10 -d 210987654321+54321 + +zint -o bar15.eps -b 13 --height=50 --border=10 -d 210987654321+54321 + +zint -o bar15.svg -b 13 --height=50 --border=10 -d 210987654321+54321 + +echo testing GS1-128 + +zint -o bar16.png -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +zint -o bar16.eps -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +zint -o bar16.svg -b 16 --height=50 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +echo testing CodaBar + +zint -o bar18.png -b 18 --height=50 --border=10 -d D765432C + +zint -o bar18.eps -b 18 --height=50 --border=10 -d D765432C + +zint -o bar18.svg -b 18 --height=50 --border=10 -d D765432C + +echo testing Code 128 + +zint -o bar20.png -b 20 --height=50 --border=10 -d "Code 128" + +zint -o bar20.eps -b 20 --height=50 --border=10 -d "Code 128" +zint -o bar20.svg -b 20 --height=50 --border=10 -d "Code 128" + +echo testing Deutshe Post Leitcode + +zint -o bar21.png -b 21 --height=50 --border=10 -d 3210987654321 + +zint -o bar21.eps -b 21 --height=50 --border=10 -d 3210987654321 + +zint -o bar21.svg -b 21 --height=50 --border=10 -d 3210987654321 + +echo testing Deutche Post Identcode + +zint -o bar22.png -b 22 --height=50 --border=10 -d 10987654321 + +zint -o bar22.eps -b 22 --height=50 --border=10 -d 10987654321 + +zint -o bar22.svg -b 22 --height=50 --border=10 -d 10987654321 + +echo testing Code 16k + +zint -o bar23.png -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" + +zint -o bar23.eps -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" + +zint -o bar23.svg -b 23 --height=50 --border=10 -d "Demonstration Code 16k symbol generated by libzint" + +zint -o bar23a.png -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar23a.eps -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar23a.svg -b 23 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +echo testing Code 49 + +zint -o bar24.png -b 24 -d "Demonstration Code 49" + +zint -o bar24.eps -b 24 -d "Demonstration Code 49" + +zint -o bar24.svg -b 24 -d "Demonstration Code 49" + +echo testing Code 93 + +zint -o bar25.png -b 25 --height=50 --border=10 -d "Code 93" + +zint -o bar25.eps -b 25 --height=50 --border=10 -d "Code 93" + +zint -o bar25.svg -b 25 --height=50 --border=10 -d "Code 93" + +echo testing Flattermarken + +zint -o bar28.png -b 28 --height=50 --border=10 -d 87654321 + +zint -o bar28.eps -b 28 --height=50 --border=10 -d 87654321 + +zint -o bar28.svg -b 28 --height=50 --border=10 -d 87654321 + +echo testing GS1 DataBar-14 + +zint -o bar29.png -b 29 --height=33 --border=10 -d 2001234567890 + +zint -o bar29.eps -b 29 --height=33 --border=10 -d 2001234567890 + +zint -o bar29.svg -b 29 --height=33 --border=10 -d 2001234567890 + +echo testing GS1 DataBar Limited + +zint -o bar30.png -b 30 --height=50 --border=10 -w 2 -d 31234567890 + +zint -o bar30.eps -b 30 --height=50 --border=10 -w 2 -d 31234567890 + +zint -o bar30.svg -b 30 --height=50 --border=10 -w 2 -d 31234567890 + +echo testing GS1 DataBar Expanded + +zint -o bar31.png -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" + +zint -o bar31.eps -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" + +zint -o bar31.svg -b 31 --height=50 --border=10 -d "[01]90012345678908[3103]001750" + +echo testing Telepen Alpha + +zint -o bar32.png -b 32 --height=50 --border=10 -d "Telepen" + +zint -o bar32.eps -b 32 --height=50 --border=10 -d "Telepen" +zint -o bar32.svg -b 32 --height=50 --border=10 -d "Telepen" + +echo testing UPC A + +zint -o bar34.png -b 34 --height=50 --border=10 -d 10987654321 + +zint -o bar34.eps -b 34 --height=50 --border=10 -d 10987654321 + +zint -o bar34.svg -b 34 --height=50 --border=10 -d 10987654321 + +echo testing UPC A - 2 digit add-on + +zint -o bar35.png -b 34 --height=50 --border=10 -d 10987654321+21 + +zint -o bar35.eps -b 34 --height=50 --border=10 -d 10987654321+21 + +zint -o bar35.svg -b 34 --height=50 --border=10 -d 10987654321+21 + +echo testing UPC A - 5 digit add-on + +zint -o bar36.png -b 36 --height=50 --border=10 -d 10987654321+54321 + +zint -o bar36.eps -b 36 --height=50 --border=10 -d 10987654321+54321 + +zint -o bar36.svg -b 36 --height=50 --border=10 -d 10987654321+54321 + +echo testing UPC E + +zint -o bar37.png -b 37 --height=50 --border=10 -d 654321 + +zint -o bar37.eps -b 37 --height=50 --border=10 -d 654321 + +zint -o bar37.svg -b 37 --height=50 --border=10 -d 654321 + +echo testing UPC E - 2 digit add-on + +zint -o bar38.png -b 37 --height=50 --border=10 -d 654321+21 + +zint -o bar38.eps -b 37 --height=50 --border=10 -d 654321+21 + +zint -o bar38.svg -b 37 --height=50 --border=10 -d 654321+21 + +echo testing UPC E - 5 digit add-on + +zint -o bar39.png -b 37 --height=50 --border=10 -d 654321+54321 + +zint -o bar39.eps -b 37 --height=50 --border=10 -d 654321+54321 + +zint -o bar39.svg -b 37 --height=50 --border=10 -d 654321+54321 + +echo testing PostNet-6 + +zint -o bar41.png -b 40 --border=10 -d 54321 + +zint -o bar41.eps -b 40 --border=10 -d 54321 + +zint -o bar41.svg -b 40 --border=10 -d 54321 + +echo testing PostNet-10 + +zint -o bar43.png -b 40 --border=10 -d 987654321 + +zint -o bar43.eps -b 40 --border=10 -d 987654321 + +zint -o bar43.svg -b 40 --border=10 -d 987654321 + +echo testing PostNet-12 + +zint -o bar45.png -b 40 --border=10 -d 10987654321 + +zint -o bar45.eps -b 40 --border=10 -d 10987654321 + +zint -o bar45.svg -b 40 --border=10 -d 10987654321 + +echo testing MSI Code + +zint -o bar47.png -b 47 --height=50 --border=10 -d 87654321 + +zint -o bar47.eps -b 47 --height=50 --border=10 -d 87654321 + +zint -o bar47.svg -b 47 --height=50 --border=10 -d 87654321 + +echo testing FIM + +zint -o bar49.png -b 49 --height=50 --border=10 -d D + +zint -o bar49.eps -b 49 --height=50 --border=10 -d D + +zint -o bar49.svg -b 49 --height=50 --border=10 -d D + +echo testing LOGMARS + +zint -o bar50.png -b 50 --height=50 --border=10 -d LOGMARS + +zint -o bar50.eps -b 50 --height=50 --border=10 -d LOGMARS + +zint -o bar50.svg -b 50 --height=50 --border=10 -d LOGMARS + +echo testing Pharmacode One-Track + +zint -o bar51.png -b 51 --height=50 --border=10 -d 123456 + +zint -o bar51.eps -b 51 --height=50 --border=10 -d 123456 + +zint -o bar51.svg -b 51 --height=50 --border=10 -d 123456 + +echo testing Pharmazentralnumber + +zint -o bar52.png -b 52 --height=50 --border=10 -d 654321 + +zint -o bar52.eps -b 52 --height=50 --border=10 -d 654321 +zint -o bar52.svg -b 52 --height=50 --border=10 -d 654321 + +echo testing Pharmacode Two-Track + +zint -o bar53.png -b 53 --height=50 --border=10 -d 12345678 + +zint -o bar53.eps -b 53 --height=50 --border=10 -d 12345678 + +zint -o bar53.svg -b 53 --height=50 --border=10 -d 12345678 + +echo testing PDF417 + +zint -o bar55.png -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +zint -o bar55.eps -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +zint -o bar55.svg -b 55 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +echo testing PDF417 Truncated + +zint -o bar56.png -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +zint -o bar56.eps -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +zint -o bar56.svg -b 56 --border=10 -d "Demonstration PDF417 symbol generated by libzint" + +echo testing Maxicode + +zint -o bar57.png -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" + +zint -o bar57.eps -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" + +zint -o bar57.svg -b 57 --border=10 --primary="999999999840012" -d "Demonstration Maxicode symbol generated by libzint" + +echo testing QR Code + +zint -o bar58.png -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" + +zint -o bar58.eps -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" + +zint -o bar58.svg -b 58 --border=10 -d "Demonstration QR Code symbol generated by libzint" + +zint -o bar58k.png -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" + +zint -o bar58k.eps -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" + +zint -o bar58k.svg -b 58 --kanji --border=10 -d "画像内の単語を非表示にする" + +echo testing Code 128 Subset B + +zint -o bar60.png -b 60 --height=50 --border=10 -d 87654321 + +zint -o bar60.eps -b 60 --height=50 --border=10 -d 87654321 + +zint -o bar60.svg -b 60 --height=50 --border=10 -d 87654321 + +echo testing Australian Post Standard Customer + +zint -o bar63.png -b 63 --border=10 -d 87654321 + +zint -o bar63.eps -b 63 --border=10 -d 87654321 + +zint -o bar63.svg -b 63 --border=10 -d 87654321 + +echo testing Australian Post Customer 2 + +zint -o bar64.png -b 63 --border=10 -d 87654321AUSPS + +zint -o bar64.eps -b 63 --border=10 -d 87654321AUSPS + +zint -o bar64.svg -b 63 --border=10 -d 87654321AUSPS + +echo testing Australian Post Customer 3 + +zint -o bar65.png -b 63 --border=10 -d "87654321 AUSTRALIA" +zint -o bar65.eps -b 63 --border=10 -d "87654321 AUSTRALIA" + +zint -o bar65.svg -b 63 --border=10 -d "87654321 AUSTRALIA" + +echo testing Australian Post Reply Paid + +zint -o bar66.png -b 66 --border=10 -d 87654321 + +zint -o bar66.eps -b 66 --border=10 -d 87654321 + +zint -o bar66.svg -b 66 --border=10 -d 87654321 + +echo testing Australian Post Routing + +zint -o bar67.png -b 67 --border=10 -d 87654321 + +zint -o bar67.eps -b 67 --border=10 -d 87654321 + +zint -o bar67.svg -b 67 --border=10 -d 87654321 + +echo testing Australian Post Redirection + +zint -o bar68.png -b 68 --border=10 -d 87654321 + +zint -o bar68.eps -b 68 --border=10 -d 87654321 + +zint -o bar68.svg -b 68 --border=10 -d 87654321 + +echo testing ISBN Code + +zint -o bar69.png -b 69 --height=50 --border=10 -d 0333638514 + +zint -o bar69.eps -b 69 --height=50 --border=10 -d 0333638514 + +zint -o bar69.svg -b 69 --height=50 --border=10 -d 0333638514 + +echo testing Royal Mail 4 State + +zint -o bar70.png -b 70 --border=10 -d ROYALMAIL + +zint -o bar70.eps -b 70 --border=10 -d ROYALMAIL + +zint -o bar70.svg -b 70 --border=10 -d ROYALMAIL + +echo testing Data Matrix + +zint -o bar71.png -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +zint -o bar71.eps -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +zint -o bar71.svg -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +zint -o bar71a.png -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar71a.eps -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar71a.svg -b 71 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +echo testing Data Matrix ECC 050 + +zint -o bar71b.png --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +zint -o bar71b.eps --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +zint -o bar71b.svg --mode=3 -b 71 --border=10 -d "Demonstration Data Matrix symbol generated by libzint" + +echo testing EAN-14 + +zint -o bar72.png -b 72 --height=50 --border=10 -d 3210987654321 + +zint -o bar72.eps -b 72 --height=50 --border=10 -d 3210987654321 +zint -o bar72.svg -b 72 --height=50 --border=10 -d 3210987654321 + +echo testing Codablock-F + +zint -o bar74.png -b 74 --border=10 -d "Demonstration Codablock-F symbol generated by libzint" + +zint -o bar74.eps -b 74 --border=10 -d "Demonstration Codablock-F symbol generated by libzint" + +zint -o bar74.svg -b 74 --border=10 -d "Demonstration Codablock-F symbol generated by libzint" + +zint -o bar74a.png -b 74 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar74a.eps -b 74 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar74a.svg -b 74 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +echo testing NVE-18 + +zint -o bar75.png -b 75 --height=50 --border=10 -d 76543210987654321 + +zint -o bar75.eps -b 75 --height=50 --border=10 -d 76543210987654321 + +zint -o bar75.svg -b 75 --height=50 --border=10 -d 76543210987654321 + +echo testing Japanese Post + +zint -o bar76.png -b 76 --border=10 -d "10000131-3-2-503" + +zint -o bar76.eps -b 76 --border=10 -d "10000131-3-2-503" +zint -o bar76.svg -b 76 --border=10 -d "10000131-3-2-503" + +echo testing Korea Post + +zint -o bar77.png -b 77 --height=50 --border=10 -d 123456 + +zint -o bar77.eps -b 77 --height=50 --border=10 -d 123456 + +zint -o bar77.svg -b 77 --height=50 --border=10 -d 123456 + +echo testing GS1 DataBar Truncated + +zint -o bar78.png -b 29 --height=13 --border=10 -d 1234567890 + +zint -o bar78.eps -b 29 --height=13 --border=10 -d 1234567890 + +zint -o bar78.svg -b 29 --height=13 --border=10 -d 1234567890 + +echo testing GS1 DataBar Stacked + +zint -o bar79.png -b 79 --border=10 -d 1234567890 + +zint -o bar79.eps -b 79 --border=10 -d 1234567890 + +zint -o bar79.svg -b 79 --border=10 -d 1234567890 + +echo testing GS1 DataBar Stacked Omnidirectional + +zint -o bar80.png -b 80 --height=69 --border=10 -d 3456789012 + +zint -o bar80.eps -b 80 --height=69 --border=10 -d 3456789012 + +zint -o bar80.svg -b 80 --height=69 --border=10 -d 3456789012 + +echo testing GS1 DataBar Expanded Stacked + +zint -o bar81.png -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +zint -o bar81.eps -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +zint -o bar81.svg -b 81 --border=10 -d "[01]98898765432106[3202]012345[15]991231" + +echo testing Planet 12 Digit + +zint -o bar82.png -b 82 --border=10 -d 10987654321 + +zint -o bar82.eps -b 82 --border=10 -d 10987654321 + +zint -o bar82.svg -b 82 --border=10 -d 10987654321 + +echo testing Planet 14 Digit + +zint -o bar83.png -b 82 --border=10 -d 3210987654321 + +zint -o bar83.eps -b 82 --border=10 -d 3210987654321 + +zint -o bar83.svg -b 82 --border=10 -d 3210987654321 + +echo testing Micro PDF417 + +zint -o bar84.png -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" + +zint -o bar84.eps -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" + +zint -o bar84.svg -b 84 --border=10 -d "Demonstration MicroPDF417 symbol generated by libzint" + +echo testing USPS OneCode 4-State Customer Barcode + +zint -o bar85.png -b 85 --border=10 -d 01234567094987654321 + +zint -o bar85.eps -b 85 --border=10 -d 01234567094987654321 + +zint -o bar85.svg -b 85 --border=10 -d 01234567094987654321 + +echo testing Plessey Code with bidirectional reading support + +zint -o bar86.png -b 86 --height=50 --border=10 -d 87654321 + +zint -o bar86.eps -b 86 --height=50 --border=10 -d 87654321 + +zint -o bar86.svg -b 86 --height=50 --border=10 -d 87654321 + +echo testing Telepen Numeric + +zint -o bar87.png -b 87 --height=50 --border=10 -d 87654321 + +zint -o bar87.eps -b 87 --height=50 --border=10 -d 87654321 + +zint -o bar87.svg -b 87 --height=50 --border=10 -d 87654321 +echo testing ITF-14 + +zint -o bar89.png -b 89 --height=50 --border=10 -d 3210987654321 + +zint -o bar89.eps -b 89 --height=50 --border=10 -d 3210987654321 + +zint -o bar89.svg -b 89 --height=50 --border=10 -d 3210987654321 + +echo testing KIX Code + +zint -o bar90.png -b 90 --border=10 -d "1231FZ13Xhs" +zint -o bar90.eps -b 90 --border=10 -d "1231FZ13Xhs" + +zint -o bar90.svg -b 90 --border=10 -d "1231FZ13Xhs" + +echo testing Aztec Code + +zint -o bar92.png -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" +zint -o bar92.eps -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" + +zint -o bar92.svg -b 92 --border=10 -d "Demonstration Aztec Code symbol generated by libzint" + +zint -o bar92a.png -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar92a.eps -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +zint -o bar92a.svg -b 92 --gs1 --border=10 -d "[01]98898765432106[02]13012345678909[10]1234567ABCDEFG[3202]012345[15]991231" + +echo testing DAFT Code + +zint -o bar93.png -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" + +zint -o bar93.eps -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" + +zint -o bar93.svg -b 93 --border=10 -d "daftdaftdaftdaftdaftdaftdaftdaftdaft" + +echo testing Micro QR Code + +zint -o bar97.png -b 97 --border=10 -d "MicroQR Code" + +zint -o bar97.eps -b 97 --border=10 -d "MicroQR Code" + +zint -o bar97.svg -b 97 --border=10 -d "MicroQR Code" + +zint -o bar97k.png -b 97 --kanji --border=10 -d "小さい" + +zint -o bar97k.eps -b 97 --kanji --border=10 -d "小さい" + +zint -o bar97k.svg -b 97 --kanji --border=10 -d "小さい" + +echo testing HIBC LIC 128 + +zint -o bar98.png -b 98 --border=10 -d "A99912345/9901510X3" + +zint -o bar98.eps -b 98 --border=10 -d "A99912345/9901510X3" + +zint -o bar98.svg -b 98 --border=10 -d "A99912345/9901510X3" + +echo testing HIBC LIC 39 + +zint -o bar99.png -b 99 --border=10 -d "A123BJC5D6E71" + +zint -o bar99.eps -b 99 --border=10 -d "A123BJC5D6E71" + +zint -o bar99.svg -b 99 --border=10 -d "A123BJC5D6E71" + +echo testing HIBC LIC Data Matrix + +zint -o bar102.png -b 102 --border=10 -d "A99912345/9901510X3" + +zint -o bar102.eps -b 102 --border=10 -d "A99912345/9901510X3" + +zint -o bar102.svg -b 102 --border=10 -d "A99912345/9901510X3" + +echo testing HIBC LIC QR-Code + +zint -o bar104.png -b 104 --border=10 -d "A99912345/9901510X3" + +zint -o bar104.eps -b 104 --border=10 -d "A99912345/9901510X3" + +zint -o bar104.svg -b 104 --border=10 -d "A99912345/9901510X3" + +echo testing HIBC LIC PDF417 + +zint -o bar106.png -b 106 --border=10 -d "A99912345/9901510X3" + +zint -o bar106.eps -b 106 --border=10 -d "A99912345/9901510X3" + +zint -o bar106.svg -b 106 --border=10 -d "A99912345/9901510X3" + +echo testing HIBC LIC MicroPDF417 + +zint -o bar108.png -b 108 --border=10 -d "A99912345/9901510X3" + +zint -o bar108.eps -b 108 --border=10 -d "A99912345/9901510X3" + +zint -o bar108.svg -b 108 --border=10 -d "A99912345/9901510X3" + +echo testing HIBC LIC Codablock F + +zint -o bar110.png -b 110 --border=10 -d "A99912345/9901510X3" + +zint -o bar110.eps -b 110 --border=10 -d "A99912345/9901510X3" + +zint -o bar110.svg -b 110 --border=10 -d "A99912345/9901510X3" + +echo testing Aztec Runes + +zint -o bar128.png -b 128 --border=10 -d 125 + +zint -o bar128.eps -b 128 --border=10 -d 125 + +zint -o bar128.svg -b 128 --border=10 -d 125 + +echo testing Code 23 + +zint -o bar129.png -b 129 --border=10 -d "12345678" + +zint -o bar129.eps -b 129 --border=10 -d "12345678" + +zint -o bar129.svg -b 129 --border=10 -d "12345678" + +echo testing EAN-8 Composite with CC-A + +zint -o bar130.png -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" + +zint -o bar130.eps -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" + +zint -o bar130.svg -b 130 --height=100 --border=10 --mode=1 --primary=1234567 -d "[21]A12345678" + +echo testing EAN-13 Composite with CC-A + +zint -o bar130a.png -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" + +zint -o bar130a.eps -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" + +zint -o bar130a.svg -b 130 --height=100 --border=10 --mode=1 --primary=331234567890 -d "[99]1234-abcd" + +echo testing UCC/EAN-128 Composite with CC-A + +zint -o bar131.png -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" + +zint -o bar131.eps -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" + +zint -o bar131.svg -b 131 --height=100 --border=10 --mode=1 --primary="[01]03212345678906" -d "[10]1234567ABCDEFG" + +echo testing UCC/EAN-128 Composite with CC-C + +zint -o bar131a.png -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" + +zint -o bar131a.eps -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" + +zint -o bar131a.svg -b 131 --height=100 --border=10 --mode=3 --primary="[00]030123456789012340" -d "[02]13012345678909[10]1234567ABCDEFG" + +echo testing RSS-14 Composite with CC-A + +zint -o bar132.png -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" + +zint -o bar132.eps -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" + +zint -o bar132.svg -b 132 --height=100 --border=10 --mode=1 --primary=361234567890 -d "[11]990102" + +echo testing RSS Limited Composite with CC-B + +zint -o bar133.png -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" + +zint -o bar133.eps -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" + +zint -o bar133.svg -b 133 --height=100 --border=10 --mode=2 --primary=351234567890 -d "[21]abcdefghijklmnopqrstuv" + +echo testing RSS Expanded Composite with CC-A + +zint -o bar134.png -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" + +zint -o bar134.eps -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" + +zint -o bar134.svg -b 134 --height=100 --border=10 --mode=1 --primary="[01]93712345678904[3103]001234" -d "[91]1A2B3C4D5E" + +echo testing UPC-A Composite with CC-A + +zint -o bar135.png -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" + +zint -o bar135.eps -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" + +zint -o bar135.svg -b 135 --height=100 --border=10 --mode=1 --primary=10987654321 -d "[15]021231" + +echo testing UPC-E Composite with CC-A + +zint -o bar136.png -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" + +zint -o bar136.eps -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" + +zint -o bar136.svg -b 136 --height=100 --border=10 --mode=1 --primary=121230 -d "[15]021231" + +echo testing RSS-14 Stacked Composite with CC-A + +zint -o bar137.png -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +zint -o bar137.eps -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +zint -o bar137.svg -b 137 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +echo testing RSS-14 Stacked Omnidirectional Composite with CC-A + +zint -o bar138.png -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +zint -o bar138.eps -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +zint -o bar138.svg -b 138 --border=10 --mode=1 --primary=341234567890 -d "[17]010200" + +echo testing RSS Expanded Stacked Composite with CC-A + +zint -o bar139.png -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" + +zint -o bar139.eps -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" + +zint -o bar139.svg -b 139 --height=150 --border=10 --mode=1 --primary="[01]00012345678905[10]ABCDEF" -d "[21]12345678" + +echo testing Channel Code + +zint -o bar140.png -b 140 --height=100 --border=10 -d "12345" + +zint -o bar140.eps -b 140 --height=100 --border=10 -d "12345" + +zint -o bar140.svg -b 140 --height=100 --border=10 -d "12345" + +echo testing Code One +zint -o bar141.png -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +zint -o bar141.eps -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +zint -o bar141.svg -b 141 --border=10 -d "Demonstration Code One symbol generated by libzint" +echo testing PNG rotation + +zint -o barrot0.png -b 130 --height=50 --border=10 --mode=1 --rotate=0 --primary=331234567890+01234 -d "[99]1234-abcd" + +zint -o barrot90.png -b 130 --height=50 --border=10 --mode=1 --rotate=90 --primary=331234567890+01234 -d "[99]1234-abcd" + +zint -o barrot180.png -b 130 --height=50 --border=10 --mode=1 --rotate=180 --primary=331234567890+01234 -d "[99]1234-abcd" + +zint -o barrot270.png -b 130 --height=50 --border=10 --mode=1 --rotate=270 --primary=331234567890+01234 -d "[99]1234-abcd" + +echo testing Extended ASCII support + +zint -o barext.png --height=50 --border=10 -d "größer" +zint -o barext.svg --height=50 --border=10 -d "größer" diff --git a/win32/zint.sln b/win32/zint.sln new file mode 100644 index 00000000..cb918305 --- /dev/null +++ b/win32/zint.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zint", "zint.vcproj", "{3169C7FA-E52C-4BFC-B7BB-E55EBA133770}" + ProjectSection(ProjectDependencies) = postProject + {5C08DC40-8F7D-475E-AA3C-814DED735A4B} = {5C08DC40-8F7D-475E-AA3C-814DED735A4B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzint", "libzint.vcproj", "{5C08DC40-8F7D-475E-AA3C-814DED735A4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release_LIB|Win32 = Release_LIB|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Debug|Win32.ActiveCfg = Debug|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Debug|Win32.Build.0 = Debug|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release_LIB|Win32.ActiveCfg = Release_LIB|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release_LIB|Win32.Build.0 = Release_LIB|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release|Win32.ActiveCfg = Release|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release|Win32.Build.0 = Release|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Debug|Win32.ActiveCfg = Debug|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Debug|Win32.Build.0 = Debug|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release_LIB|Win32.ActiveCfg = Release_LIB|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release_LIB|Win32.Build.0 = Release_LIB|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release|Win32.ActiveCfg = Release|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/win32/zint.vcproj b/win32/zint.vcproj new file mode 100644 index 00000000..b6868a96 --- /dev/null +++ b/win32/zint.vcproj @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zint-qt.desktop b/zint-qt.desktop new file mode 100644 index 00000000..2d46bc7a --- /dev/null +++ b/zint-qt.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Zint Barcode Studio +GenericName=Zint Barcode Studio +Exec=zint-qt +Icon=zint +Terminal=false +Type=Application +Categories=Utility; diff --git a/zint.nsi b/zint.nsi new file mode 100644 index 00000000..166ec24d --- /dev/null +++ b/zint.nsi @@ -0,0 +1,205 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; @(#) $Id: zint.nsi,v 1.1 2009/11/17 22:23:06 hooper114 Exp $ +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Script generated by the HM NIS Edit Script Wizard. +; HM NIS Edit Wizard helper defines +; ver 1.0.0.1 20090914 tgotic removed WinSxS check +;****************************************************************************** +!define PRODUCT_NAME "Zint" +!define PRODUCT_EXE "qtZint.exe" +!define PRODUCT_VERSION "2.3.0.0" +!define PRODUCT_WEB_SITE "http://www.zint.org.uk" +!define PRODUCT_PUBLISHER "Robin Stuart & BogDan Vatra" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_EXE}" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir" +;****************************************************************************** +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "Setup_${PRODUCT_NAME}_${PRODUCT_VERSION}.exe" +BrandingText "GPLv3, ${PRODUCT_PUBLISHER}" +;****************************************************************************** +;ShowInstDetails show -ne zapisuje podatke u log datoteku +ShowInstDetails show +ShowUnInstDetails show + +XPStyle on +SetCompress auto +SetCompressor lzma +AutoCloseWindow false +CRCCheck force +;****************************************************************************** +; MUI 1.8 compatible ------ +!define MULTIUSER_EXECUTIONLEVEL Highest +!define MULTIUSER_MUI +!define MULTIUSER_INSTALLMODE_COMMANDLINE +!define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCT_NAME}\" +!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" +!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "InstallLocation" +;****************************************************************************** +!include MultiUser.nsh +!include MUI2.nsh +!include LogicLib.nsh +!include WinMessages.nsh +!include FileFunc.nsh +;****************************************************************************** +; MUI Settings +!define MUI_ABORTWARNING +; odkomentirati za prikaz MUI_PAGE_INSTFILES +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +;****************************************************************************** +Var USER +Var ICONS_GROUP +;****************************************************************************** +; Welcome page +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "gpl-3.0.txt" +; Mixed mode instalation page +!insertmacro MULTIUSER_PAGE_INSTALLMODE +; Components page +; !insertmacro MUI_PAGE_COMPONENTS +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +!define MUI_STARTMENUPAGE_NODISABLE +!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${PRODUCT_NAME}" +!define MUI_STARTMENUPAGE_REGISTRY_ROOT SHCTX +!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}" +!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +;Finish page +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH +; MUI end ------ +;****************************************************************************** +; Language files +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_RESERVEFILE_LANGDLL +;****************************************************************************** +Function .onInit + !insertmacro MULTIUSER_INIT +FunctionEnd +;****************************************************************************** +Function startInstall + SetOutPath "$INSTDIR" + StrCpy $USER 0 + UserInfo::GetName + Pop $USER + + ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 + +# LogSet on + DetailPrint "--------------------------------------------------------------------------------" + DetailPrint "Install start $2-$1-$0 $4:$5:$6 user:$USER ($MultiUser.Privileges)" + DetailPrint "--------------------------------------------------------------------------------" +FunctionEnd +;****************************************************************************** +;****************************************************************************** +Section ${PRODUCT_NAME} SEC01 + SectionIn RO + Call startInstall + + SetOverwrite ifnewer + File ".\frontend_qt4\release\${PRODUCT_EXE}" + File ".\win32\Release\zint.exe" + + WriteUninstaller "$INSTDIR\uninst.exe" + +!insertmacro MUI_STARTMENU_WRITE_BEGIN Application + CreateDirectory "$SMPROGRAMS\$ICONS_GROUP" + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\qtZint.lnk" "$INSTDIR\${PRODUCT_EXE}" + CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe" +!insertmacro MUI_STARTMENU_WRITE_END + +SectionEnd +;****************************************************************************** +Section -Post + WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\${PRODUCT_EXE}" + WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" "Path" "$INSTDIR" + + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXE}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLUpdateInfo" "${PRODUCT_WEB_SITE}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "InstallSource" "$EXEDIR" + WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoModify" 1 + WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoRepair" 1 + + DetailPrint "--------------------------------------------------------------------------------" + ClearErrors +SectionEnd +;****************************************************************************** +LangString MSG1 ${LANG_ENGLISH} "$(^Name) was successfully removed from your computer." +LangString MSG2 ${LANG_ENGLISH} "${PRODUCT_EXE} could not be closed.$\r$\nTry again?" +LangString MSG3 ${LANG_ENGLISH} "Are you sure you want to completely remove $(^Name) and all of its components?" +LangString MSG4 ${LANG_ENGLISH} "$(^Name) application" +LangString MSG5 ${LANG_ENGLISH} "Unable to create $INSTDIR" +;****************************************************************************** +Function un.onInit + !insertmacro MULTIUSER_UNINIT + StrCpy $USER 0 + UserInfo::GetName + Pop $USER + + ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 + +# LogSet on + DetailPrint "--------------------------------------------------------------------------------" + DetailPrint "Uninstall start $2-$1-$0 $4:$5:$6 user:$USER ($MultiUser.Privileges)" + DetailPrint "--------------------------------------------------------------------------------" + + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 $(MSG3) /SD IDYES IDYES +2 + Abort +FunctionEnd +;****************************************************************************** +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK $(MSG1) /SD IDOK + DetailPrint "--------------------------------------------------------------------------------" + DetailPrint "*** Uninstall finish OK ***" + DetailPrint "--------------------------------------------------------------------------------" +FunctionEnd +;****************************************************************************** +Function un.onUninstFailed + DetailPrint "--------------------------------------------------------------------------------" + DetailPrint "*** Uninstall finish FAILED ***" + DetailPrint "--------------------------------------------------------------------------------" +FunctionEnd +;****************************************************************************** +Section Uninstall + DetailPrint "--------------------------------------------------------------------------------" + DeleteRegKey SHCTX "${PRODUCT_UNINST_KEY}" + DeleteRegKey SHCTX "${PRODUCT_DIR_REGKEY}" + +!insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP + RmDir /r "$SMPROGRAMS\$ICONS_GROUP" + Delete /REBOOTOK "$INSTDIR\${PRODUCT_EXE}" + Delete /REBOOTOK "$INSTDIR\zint.exe" + Delete /REBOOTOK "$INSTDIR\uninst.exe" + Delete /REBOOTOK "$INSTDIR\install.log" + RmDir /REBOOTOK "$INSTDIR" + +SectionEnd +;****************************************************************************** +VIProductVersion ${PRODUCT_VERSION} +VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "${PRODUCT_PUBLISHER}" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "${PRODUCT_NAME} Setup" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${PRODUCT_VERSION}" +VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright 2009 Robin Stuart & BogDan Vatra" +VIAddVersionKey /LANG=${LANG_ENGLISH} "License" "GNU General Public License version 3" +VIAddVersionKey /LANG=${LANG_ENGLISH} "WWW" "${PRODUCT_WEB_SITE}" +;****************************************************************************** diff --git a/zint.png b/zint.png new file mode 100644 index 0000000000000000000000000000000000000000..dc723995f452025773834e43400bd4c5d32aa44f GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Y)RhkE)4%c zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPyx3HLiRPrRLb3jwPJY5_^GVZ;N zJeb#Pz*EcLx-NRDT-nXi|NravigcAb>bzyLc*)WEN?mb6Qqz6zZOIHgzndOMW_`WO z=)nC*%h`6` x9dF;M7kjz%zv-gecP7SFT`hjW;q3W?ac*?k?yMvo8Pu literal 0 HcmV?d00001 diff --git a/zint.spec b/zint.spec new file mode 100644 index 00000000..f74d0f96 --- /dev/null +++ b/zint.spec @@ -0,0 +1,144 @@ +Name: zint +Version: 2.3.1 +Release: 2%{?dist} +Summary: A barcode generator and library +License: GPLv3+ +URL: http://www.zint.org.uk +Source: http://downloads.sourceforge.net/project/%{name}/%{name}/%{version}/%{name}-%{version}.src.tar.gz +Group: Applications/Engineering +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + +# Reset locales to "C" when exporting to EPS or SVG in order to force +# decimal points in all language environments. +# This issue has been reported upstream: +# http://sourceforge.net/mailarchive/forum.php?thread_name=4BF78012.7090508%40uos.de&forum_name=zint-barcode +Patch0: zint-locale.patch + +BuildRequires: cmake +BuildRequires: libpng-devel +BuildRequires: zlib-devel + +%description +Zint is a C library for encoding data in several barcode variants. The +bundled command-line utility provides a simple interface to the library. +Features of the library: +- Over 50 symbologies including all ISO/IEC standards, like QR codes. +- Unicode translation for symbologies which support Latin-1 and + Kanji character sets. +- Full GS1 support including data verification and automated insertion of + FNC1 characters. +- Support for encoding binary data including NULL (ASCII 0) characters. +- Health Industry Barcode (HIBC) encoding capabilities. +- Output in PNG, EPS and SVG formats with user adjustable sizes and colors. +- Verification stage for SBN, ISBN and ISBN-13 data. + + +%package -n zint-devel +Summary: Library and header files for %{name} +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description -n zint-devel +C library and header files needed to develop applications using %{name}. +The API documentation can be found ont the project website: +http://www.zint.org.uk/zintSite/Manual.aspx + + +%package -n zint-qt +Summary: Zint Barcode Studio GUI and library +Group: Applications/Engineering +Requires: %{name} = %{version}-%{release} +BuildRequires: qt-devel >= 4.4 +BuildRequires: desktop-file-utils + +%description -n zint-qt +Zint Barcode Studio is a Qt-based GUI which allows desktop users to generate +barcodes which can then be embedded in documents or HTML pages, and a library +which can be used to incorporate barcode generation functionality into other +software. + + +%package -n zint-qt-devel +Summary: Library and header files for %{name}-qt +Group: Development/Libraries +Requires: %{name}-devel = %{version}-%{release} +Requires: %{name}-qt = %{version}-%{release} + +%description -n zint-qt-devel +C library and header files needed to develop applications using %{name}-qt. + + +%prep +%setup -q +%patch0 -p1 + +# remove BSD-licensed file required for Windows only (just to ensure that this package is plain GPLv3+) +rm -f backend/ms_stdint.h + +# remove bundled getopt sources (we use the corresponding Fedora package instead) +rm -f frontend/getopt*.* + +%build +%cmake CMakeLists.txt +make VERBOSE=1 %{?_smp_mflags} + +cat <zint-qt.desktop +[Desktop Entry] +Name=Zint Barcode Studio +GenericName=Zint Barcode Studio +Exec=zint-qt +Icon=zint +Terminal=false +Type=Application +Categories=Utility; +EOF + + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +rm -rf $RPM_BUILD_ROOT/%{_datadir}/cmake +install -D -p -m 644 frontend_qt4/images/%{name}_white.png %{buildroot}/usr/share/pixmaps/%{name}.png +install -D -p -m 644 %{name}-qt.desktop %{buildroot}%{_datadir}/applications/%{name}-qt.desktop +desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}-qt.desktop + +%clean +rm -rf $RPM_BUILD_ROOT + + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig +%post -n %{name}-qt -p /sbin/ldconfig +%postun -n %{name}-qt -p /sbin/ldconfig + + +%files +%defattr(-,root,root,-) +%doc COPYING readme +%{_bindir}/%{name} +%{_libdir}/libzint.so.* + +%files -n %{name}-devel +%defattr(-,root,root,-) +%{_includedir}/%{name}.h +%{_libdir}/libzint.so + +%files -n %{name}-qt +%defattr(-,root,root,-) +%{_bindir}/%{name}-qt +%{_libdir}/libQZint.so.* +%{_datadir}/applications/%{name}-qt.desktop +%{_datadir}/pixmaps/%{name}.png + +%files -n %{name}-qt-devel +%defattr(-,root,root,-) +%{_includedir}/qzint.h +%{_libdir}/libQZint.so + + +%changelog +* Sat May 22 2010 Martin Gieseking - 2.3.1-2 +- Added patch to fix export issue + +* Fri May 21 2010 Martin Gieseking - 2.3.1-1 +- initial package